jre jdk for español developers java java-8 java-9

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í:

¿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.asList no sigue esto: si se crea con una matriz de un subtipo (por ejemplo, String[] ), su toArray() devolverá una matriz del mismo tipo (porque usa clone() ) en lugar de un Object[] .

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-arg toArray(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.