Aller au contenu

[Résolu] ClassCastException malgré des generics


BreizFenrir

Messages recommandés

Bonjour,

Je suis en forme en ce moment. Enfin c'est mon code qui ne m'aime pas. Enfin bref, j'ai plusieurs classes de définies où j'utilise les generics ; c'est beau, c'est propre, ça compile, et à l'exécution PAF ! je me ramasse une ClassCastException. Voici le message d'erreur :

Exception in thread "Thread-2" java.lang.ClassCastException: com.orange.sondeqosrbci.database.DatabasesConfig
	at com.orange.sondeqosrbci.util.monitor.AbstractMonitorManager.run(AbstractMonitorManager.java:43)
	at java.lang.Thread.run(Thread.java:595)

Le problème

La ligne 43 en question est la suivante, où fItemsConfigMapper est initialisé dans le constructeur :

public abstract class AbstractMonitorManager<S, T extends AbstractSetConfig<S>>
	implements Runnable {
...
public void run() {
...
	T itemsConfig = fItemsConfigMapper.get(); // ICI
...
}
...
private final AbstractConfigMapper<T> fItemsConfigMapper;
}

Bien évidemment, la classe étant abstraite, elle n'est pas appelée comme cela, mais via une classe qui l'hérite. Plus précisément celle-ci :

public class DatabaseMonitorManager
	extends AbstractMonitorManager<Database, DatabasesConfig> {
...
}

Il est aussi intéressant, bien sûr, de voir comment est défini AbstractConfigMapper, histoire de bien voir qu'il n'y a pas d'erreur dû à une mauvaise utilisation.

public abstract class AbstractConfigMapper<T extends AbstractConfig> {
public T get() {
...
}
}

Enfin, il faut savoir que DatabasesConfig hérite de AbstractSetConfig<Database>, qui elle-même hérite de AbstractConfig tout en implémentant Set<T>.

Si vous ne voyez pas d'erreur à ce niveau-là, moi non plus. Mais c'est encore plus bizarre quand on fait quelques petits tests.

Test : changer le type de itemsConfig pour essayer de déterminer la cause de l'exception

J'ai effectué le test en modifiant le type de itemsConfig sur la ligne où il est déclaré (et seulement cette ligne, après avoir commenté le code utilisant la variable), de la façon suivante :

		Object itemsConfig = fItemsConfigMapper.get();  // OK
	Cloneable itemsConfig = fItemsConfigMapper.get();  // OK (implémenté par AbstractConfig)
	AbstractConfig itemsConfig = fItemsConfigMapper.get();  // OK
	Set itemsConfig = fItemsConfigMapper.get();  // ClassCastException (implémenté par AbstractSetConfig)
	AbstractSetConfig itemsConfig = fItemsConfigMapper.get();  // ClassCastException
	DatabasesConfig itemsConfig = (DatabasesConfig) fItemsConfigMapper.get();  // OK

Je suis assez surpris de la présence de l'exception lors de l'utilisation de types utilisant les generics, et pas pour les autres quand bien même ils hériteraient de ces derniers !

La grande question

Qu'est-ce qui expliquerait ce genre de comportement de la part de la JVM ? Que fais-je mal ?

Lien vers le commentaire
Partager sur d’autres sites

Je suis un boulet. J'avais oublié que dans la librairie gérant les fichiers de configuration j'avais déjà les classes DatabasesConfig et DatabasesConfigMapper définies. Dans le même namespace en plus. Et donc ce sont ces dernières qui étaient utilisées, et non les autres (les différences n'étant que relativement légères).

Donc bon, pendez-moi !

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...