java - for - ¿Por qué Arrays.asList(…).toArray(). GetClass() da resultados diferentes en JDK 8 y 9?
java for developers (2)
Esta pregunta ya tiene una respuesta aquí:
- array cast Java 8 vs Java 9 2 respuestas
¿Por qué la siguiente condición devuelve true con JDK 8, mientras que devuelve false con JDK 9?
String[].class == Arrays.asList("a", "b").toArray().getClass()
El tipo de List devuelto por asList es Arrays$ArrayList . El método toArray en JDK 8 en esa clase es:
@Override
public Object[] toArray() {
return a.clone();
}
Pero en JDK 9+ es:
@Override
public Object[] toArray() {
return Arrays.copyOf(a, a.length, Object[].class);
}
En ambos casos String[] se pasa una String[] a asList , pero en el caso de JDK 8 se clona, lo que conserva su tipo de matriz ( String[] ), y en JDK 9+ se copia utilizando Arrays.copyOf con la nueva matriz explícita tipo de Object[] .
Esta diferencia significa que en JDK 8 Arrays.asList("a", "b").toArray().getClass() devuelve String[] y en JDK 9+ devuelve Object[] , por lo que en JDK 9+ su expresión evaluar a false .
La razón de este cambio proviene de JDK-6260652 con la motivación:
La documentación de la colección afirma que
collection.toArray()es "idéntico en función" a
collection.toArray(new Object[0]);Sin embargo, la implementación de
Arrays.asListno sigue esto: si se crea con una matriz de un subtipo (por ejemplo,String[]), sutoArray()devolverá una matriz del mismo tipo (porque usaclone()) en lugar de unObject[].Si uno trata más tarde de almacenar no cadenas (o lo que sea) en esa matriz, se lanza una
ArrayStoreException.
Así que este cambio se hizo para arreglar el comportamiento anterior.
Si este es un problema para usted, la nota de lanzamiento relacionada ofrece esto como una solución alternativa:
Si se produce este problema,
toArray(T[])escribir el código para usar el formulario one-argtoArray(T[])y proporcione una instancia del tipo de matriz deseado. Esto también eliminará la necesidad de un yeso.
String[] array = list.toArray(new String[0]);
Yo diría que esto fue un error en JDK 8 y antes de que se haya solucionado.
List<T>.toArray() siempre se declaró como Object[] devuelto Object[] (ver JavaDoc ) - que en efecto devolvió la String[] en un caso especial fue un error.