Es:
add(i.toArray(new Animal[i.size()]))
List.toArray devuelve un Object[]
, independientemente del argumento del tipo en la lista: a pesar de que se podría escribir new List<String>().toArray()
, obtendrá una Object[]
. Sin embargo, el version of toArray that takes an array to fill devuelve una matriz con el tipo correcto: si escribe new List<String>().toArray(new String[0])
, obtendrá un String[]
. Tenga en cuenta que el tamaño de la matriz que ingresa ni siquiera tiene que coincidir con el tamaño de la lista, aunque es una buena práctica asegurarse de que así sea.
Esto se debe a una característica ligeramente delicada de los genéricos. A primera vista, puede pensar que String[]
y List<String>
significan cosas similares para sus tipos de base: una es una matriz de cadenas y la otra es una lista de cadenas.
Sin embargo, de hecho son muy diferentes.
Una matriz es una primitiva del lenguaje, y tiene su tipo cocido en ella. Si tomó un editor hexadecimal y miró una instancia de matriz en la memoria en la JVM, podría encontrar (en algún lugar cercano) un registro del tipo de objetos que contiene. Eso significa que si toma una instancia de una matriz de algún tipo de componente desconocido, puede find out what that type is. Por el contrario, significa que si va al create an instance of an array, necesita saber qué tipo de componente desea.
El List
, por el contrario, utiliza los genéricos, que en Java se implementa con type erasure, lo que significa que, en términos generales, es algo que existe en el compilador, pero no en tiempo de ejecución (el compilador pueda verificar que se hazlo bien, pero la JVM no puede). Esto lleva a una implementación simple y eficiente (una lo suficientemente simple como para haber sido agregada a Java pregenéricos sin cambiar la JVM), pero tiene algunas deficiencias, en particular, que en el tiempo de ejecución, no hay forma de saber cuál es el argumento de tipo en cualquier instancia particular de una clase genérica es, porque los argumentos de tipo solo existen en el compilador. Debido a que depende de la instancia List
manejar toArray()
, lo único que puede hacer es crear un Object[]
. Simplemente no sabe de un tipo más específico para usar.
Una forma de ver esto es que las matrices tienen un argumento de tipo como parte de su clase, mientras que List
s tienen un argumento de tipo como parte de su tipo, y puesto que los objetos tienen clases pero las variables tienen tipos, no puede obtener el argumento de tipo de un List
de un objeto, solo de una variable que contiene un objeto (como un lado, tampoco puede obtener el argumento de tipo de una matriz de una variable que contiene una matriz (considere Object[] array = new String[0];
), pero eso realmente no importa porque, la variable le permite agarrar un objeto, a menos que sea nulo).
Hervir esto a código, el problema es:
public <E> E[] createSimilarlyTypedArray(List<E> list) {
Class<E> componentType = list.???; // there is no way to do this
return Arrays.newInstance(componentType, list.size());
}
No entiendo la pregunta. Hiciste tu propio método 'Agregar (Animal ...)' pero estás llamando ArrayList.add (Objeto) y no el tuyo. ¿Porqué es eso? Por favor, edite la pregunta con el contexto del código. ¿Ese bloque de código está dentro de tu método'add'? Si su único problema es que no puede lanzar Object [] a Animal [], siga @Tom answer. – aalku
Solo una nota para el futuro: si tiene un error de compilación, copie el mensaje de error completo y también las líneas de código fuente relevantes para este mensaje. –