Pourquoi la condition suivante retourne true
avec JDK 8, alors qu'elle retourne false
avec JDK 9?
String[].class == Arrays.asList("a", "b").toArray().getClass()
Le type List
renvoyé par asList
est Arrays$ArrayList
. La méthode toArray
dans JDK 8 sur cette classe est:
@Override
public Object[] toArray() {
return a.clone();
}
Mais dans JDK 9+ c'est:
@Override
public Object[] toArray() {
return Arrays.copyOf(a, a.length, Object[].class);
}
Dans les deux cas, un String[]
Est passé à asList
, mais dans le cas JDK 8, il est cloné, qui conserve son type de tableau (String[]
), Et dans JDK 9+ il est copié à l'aide de Arrays.copyOf
avec le nouveau type de tableau explicite de Object[]
.
Cette différence signifie que dans JDK 8 Arrays.asList("a", "b").toArray().getClass()
renvoie String[]
Et dans JDK 9+ il retourne Object[]
, Donc dans JDK 9+ votre expression sera évaluée à false
.
La raison de ce changement vient de JDK-6260652 avec la motivation:
La documentation de la Collection affirme que
collection.toArray()
est "identique en fonction" à
collection.toArray(new Object[0]);
Cependant, l'implémentation de
Arrays.asList
Ne suit pas ceci: s'il est créé avec un tableau d'un sous-type (par exempleString[]
), SatoArray()
renverra un tableau du même type (car il utiliseclone()
) au lieu d'unObject[]
.Si l'on essaie plus tard de stocker des non-chaînes (ou autre) dans ce tableau, un
ArrayStoreException
est jeté.
Cette modification a donc été apportée pour corriger le comportement précédent.
Si c'est un problème pour vous, le release note associé propose ceci comme solution de contournement:
Si ce problème se produit, réécrivez le code pour utiliser le formulaire à un argument
toArray(T[])
et fournissez une instance du type de tableau souhaité. Cela éliminera également le besoin d'un casting.String[] array = list.toArray(new String[0]);
Je dirais que c'était un bug dans JDK 8 et avant cela a été corrigé.
List<T>.toArray()
a toujours été déclaré comme retournant Object[]
(voir JavaDoc ) - qu'il a effectivement renvoyé String[]
dans un cas particulier était une erreur.