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[]
?
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]).
É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")
?
[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.