Christophe Jacquet

Joies des generics

Voici un problème de Java qui a l’air insoluble : je veux faire une méthode qui me renvoie un tableau d’un type générique T, sachant que pour générer ledit tableau, j’utilise temporairement un ArrayList<T>. Problème : comment récupérer de façon type safe le tableau à partir de l’ArrayList<T>, sachant que je dispose d’une méthode toArray() qui renvoie un Object[] et toArray(T[]) qui renvoie un T[] ?

Première idée

public static <T> T[] truc(T a) {
	List<T> liste = new ArrayList<T>();
	liste.add(a);
	return liste.toArray(new T[] {});
}

Ça ne compile pas, parce que Java ne peut pas instancier de tableaux du type paramètre T (en raison de l’erasure, i.e. la suppression des types paramètres lors de la compilation, la JVM ne saurait tout simplement pas quelle classe instancier[1]).

Deuxième idée

Étant incapable d’instancier un T[], je décide donc de me rabattre sur la méthode qui me renvoie un Object[], et caster vers T[] :

	...
	return (T[]) liste.toArray();
	...

Sauf que le compilateur Java génère un warning « unchecked cast ». Ça compile et ça marche, mais on perd la type safety (qui n’est garantie que la compilation du projet entier ne génère aucun « unchecked cast »).

Des idées meilleures qu’un @SuppressWarnings("unchecked") ?

Notes

[1] Java interdit aussi l’instanciation de types génériques du genre List<String>[], mais c’est un autre problème, lié à la covariance des tableaux… Les deux problèmes sont très bien expliqués chez IBM.

HTML5 valide ? © . ✍ Contact. Mentions légales.