java - objeto - ¿Por qué List<String>.toArray() devuelve Object[] y no String[]? cómo solucionar esto?
tostring java (5)
¿Alguien sabe por qué Java 1.6 tiene este comportamiento?
List<String> list = ArrayList<String>();
String[] arr = (String[]) list.toArray();
Y obtengo una ClassCastException, porque devuelve Object [] y no String [].
Pensé que List<T>.toArray()
debería devolver T [] - no? ¿Alguien tiene una respuesta por qué este inconveniente existe en el idioma? ¿Y también cómo solucionar esto? ¿Cómo obtengo un String [] de List<String>
sin bucles a través de los elementos?
Debido a que los arreglos han estado en Java desde el principio, mientras que los genéricos solo se introdujeron en Java 5. Y el método List.toArray()
se introdujo en Java 1.2, antes de que existieran los genéricos, por lo que se especificó para devolver Object[]
. Muchos códigos existentes ahora esperan que List.toArray()
devuelva Object[]
, por lo que no se puede cambiar ahora.
Además, los genéricos se borran en tiempo de ejecución, por lo que ArrayList
no podría incluso construir una matriz del tipo correcto si así lo deseara.
La laguna para esto es el List.toArray(T[])
, que le devolverá una matriz del tipo correcto, siempre que le proporcione una matriz del tipo correcto para que sepa qué tipo usar.
La solución alternativa será usar:
List<String> list = new ArrayList<>();
list.add("Sputnik");
list.add("Explorer");
//String[] str = list.toArray();
Esto está obligado a arrojar un: tipos incompatibles: Objeto [] no se puede convertir a String [] error
Instead use:
String[] str = list.toArray(new String[0]);
or
String[] str = list.toArray(new String[list.size()]);
Las razones son dos:
El método precedió a Generics y no pudieron cambiar la firma sin romper la compatibilidad hacia atrás.
En cualquier caso, como la
List
se construye sin unaClass<T>
no hay forma de que la implementación construya una matriz de tipoT
Necesita pasar una matriz para que su tipo de tiempo de ejecución se pueda utilizar como una pista por toArray
. Pruebe toArray(new String[0])
lugar. También puede pasar en una matriz pre-dimensionada.
Para entender, considere qué tipo de borrado tendría que hacer para hacer
new T[4]
trabajo. Si Java lo permitió, lo mejor que podría hacer después de la eliminación es
new Object[4]
La mayoría de toArray
implementaciones de toArray
usan java.lang.reflect.Array
para construir una matriz de salida del tipo correcto dada una sugerencia de tipo pasada como Class
.
Para entender por qué sucede eso, solo eche un vistazo al javadoc de Collection.toArray()
y luego mire el método Collection.toArray(T[] a)
. También tenga en cuenta que los genéricos en Java se borran en el tiempo de ejecución.