Incompatibilité de Type: impossible de convertir de Classe <..> Classe <...>
J'ai 'hérité' une Eclipse RCP projet qui semble bien fonctionner avec une plate-forme cible basée autour de 3.6. Cependant, aller de l'avant, nous avons besoin de mettre à jour vers la dernière version de la plate-forme, mais quand je change la plate-forme cible à 3,7 (ou 4.2), j'ai une poignée d'erreurs le long de la lignes de
Type mismatch: cannot convert from Class<capture#1-of ?> to Class<? extends IDatasetProvider>
N'importe qui peut suggèrent ou fournir une explication des raisons pour lesquelles cela peut bien fonctionner dans la 3.6, mais pas en 3,7 (et plus tard)? Toutes les idées quant à l'endroit où je voudrais commencer à résoudre ce serait aussi génial!
Un extrait du code de l'origine de l'erreur (qui apparaît à la b.loadClass partie):
List<Class<? extends IDatasetProvider>> list = new LinkedList<Class<? extends IDatasetProvider>>();
ClassMap<IDatasetProvider, List<String>> map = new ClassMap<IDatasetProvider, List<String>>();
for (IConfigurationElement e : elements)
{
try
{
Bundle b = Platform.getBundle(e.getContributor().getName());
String viewId = e.getAttribute("viewId");
Class<? extends IDatasetProvider> datasetType = b.loadClass(e
.getAttribute("datasetProvider"));
...
...
...
}
}
Il y a également 3 (peut-être) des avertissements liés à
IDatasetProvider is a raw type. References to generic type IDatasetProvider<T> should be parameterized
Si je revenir à notre 3.6 plate-forme, tout fonctionne à nouveau.
EDIT: merci fixe à l'aide d'Alexis et gzukmin.
J'ai utilisé le code suivant, plus précisément de la coulée de Class<? extends IDatasetProvider>
plutôt que de simplement Class
:
Class<? extends IDatasetProvider> datasetType =
(Class<? extends IDatasetProvider>) b.loadClass(e.getAttribute("datasetProvider"));
Si il n'y a aucune raison que je devrais envisager de simplement jeter le plus générique Class
, s'il vous plaît laissez-moi savoir!
- Je suppose qu'il va être divers pour voir
loadClass
signature de la méthode. - Entendez-vous le:
Class<?> loadClass(String name) throws ClassNotFoundException;
ligne à partir de l'organisation.osgi.cadre.La classe Bundle? - Êtes-vous d'utiliser la même version de Java sous 3.6, 3.7 et 4.2?
- Exactement. Donc, vous essayez d'affecter un
Class<?>
objet de laClass<? extends IDatasetProvider>
variable, qui produisent de l'erreur (je suppose). C'est parce queClass<?>
n'est pas sous-type deClass<? extends IDatasetProvider>
. Peut-être dans la version précédenteClass<?>
était un rawtypeClass
et au lieu de l'erreur du compilateur produit des avertissements ont été ignorés. - C'est JDK 1.6 / RE6 pour toutes les versions d'eclipse.
- Vous avez été correct gkuzmin. Juste pour confirmer, dans la version 3.6/cible,
loadClass
n'a tout simplement retourner un rawtypeClass
.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez simplement le jeter à raw type comme ceci:
Noter que ceci:
Ajouter plus de mises en garde à propos de raw types et non des moulages.
Exploser lors de l'exécution si votre classe s'avère ne pas étendre
IDatasetProvider
. Et pas sur le casting de l'emplacement, mais plus tard, quand vous essayez d'utiliser la classe. Donc, il pourrait être une bonne idée de vérifier avec(voir Javadoc).
Class<? extends IDatasetProvider>
et éteignez pas cochée fonte d'avertissement avec@SuppressWarning("unchecked")
. Il aura le même effet que le code que vous avez proposé, mais sans raw typeClass
et d'avertissement du compilateur. Et comment avez-vous l'intention de vérifier si la classe s'étend en faitIDatasetProvider
?@SuppressWarning
dans les deux cas. Vous avez encore de l'avertissement à propos de raw typeIDatasetProvider
si vous avez jeté àClass<? extends IDatasetProvider>
. Si le casting deClass<? extends IDatasetProvider<?>>
compile, il serait vraiment mieux. Voir édité réponse à la dernière question.isAssignableFrom
méthode. Je pense que cette méthode est très utile si la classe n'est pas générique.@SuppressWarnings("unchecked")
et pas @SuppressWarning("unchecked")Class
il serait préférable d'utiliserb.loadClass(e.getAttribute("datasetProvider")).asSubclass(IDatasetProvider.class)
, qui (a) ne doit pas exiger un cast explicite, (b) de ne pas générer des avertissements et (c) fail-fast avec unClassCastException
si le chargé de classe n'est pas une mise en œuvre deIDatasetProvider
.