son retorno qué objeto interfaces instanciar genericos generico genericas generica crear como clases arreglos java arrays generics

retorno - qué son generics en java



¿Cuál es la alternativa más fácil a una matriz genérica en Java? (7)

Supongamos que tengo esto:

class test<T> { private T[] elements; private int size; public test(int size) { this.size = size; elements = new T[this.size]; } }

Parece que esto no es posible porque el compilador no sabe a qué constructor llamar una vez que intenta reemplazar el código genérico o algo así. Lo que me pregunto es, ¿cómo voy a hacer esto? Me imagino que es posible, dado lo fácil que es hacerlo en C ++.

Editar: Lo siento, olvidé la [] en la declaración de elementos.


El problema es que dado que el parámetro de tipo genérico T se transforma en Object por el compilador (se llama borrado de tipo ), realmente se crea una matriz de Object . Lo que puede hacer es proporcionar una Class<T> a la función:

class test<T> { private T[] elements; private int size; public test(Class<T> type, int size) { this.size = size; elements = (T[]) Array. newInstance(type, size); } }

Encontrará una mejor explicación aquí: Angelika Langer: ¿Puedo crear una matriz cuyo tipo de componente sea un parámetro de tipo?


La alternativa más fácil a una matriz genérica es usar una lista.


Puedo estar equivocado, pero su declaración parece extraña, ¿no debería tener:

private T[] elements;


El campo de tamaño parece redundante. Podrías tener elements.length en lugar de size.

class Test<T> { private final T[] elements; public test(int size) { elements = (T[]) new Object[size]; } }

O puede reemplazar la clase de prueba con una ArrayList. es decir, descartar la clase por completo.


Hay dos soluciones que no requieren pasar en el objeto de la clase. En ambos supongo que, dado que es una variable privada, usted es la única persona que le agrega cosas, y el mundo exterior no lo ve.

Una es simplemente usar un Object Objeto de matriz simple Object[] . La desventaja es que perderá los beneficios de los genéricos y tendrá que lanzar cosas que salen de él, lo que hace que el código sea más feo. Pero ya que eres la única persona que pone cosas en él, entonces el reparto siempre debe estar seguro. El exterior no necesita saber qué está pasando.

Las otras opciones son una especie de truco. Usted crea un Object[] y luego lo "lanza" a T[] . Técnicamente esto es ilegal, porque Object[] y T[] son diferentes tipos de tiempo de ejecución y los primeros no se pueden convertir a este último. Pero siempre que no pase la matriz fuera de la clase (por ejemplo, devolverla o algo así), entonces no causará ningún problema, ya que T[] se borrará de todos modos en Object[] , y no se lanzará ningún elemento en realidad. realizado. Luego puede obtener los beneficios de los genéricos en su clase para una codificación más fácil, pero debe tener mucho cuidado de no pasar esa matriz a nadie que realmente espera una T[] , porque no lo es.


Tiendo a evitar arreglos básicos y uso ArrayLists (o listas similares) siempre que sea posible por varias razones. Los dos más importantes son:

  1. No necesito la semántica de la matriz calva. No hay nada sobre la notación de corchetes (es decir, la abreviatura de la aritmética del puntero) que me hace la vida más fácil.

  2. Si utilizo Listas, me estoy preparando para usar estructuras más sofisticadas habilitadas por concurrencia en la línea, según sea necesario. Por ejemplo, es muy fácil reemplazar una ArrayList con una CopyOnWriteArrayList .

Por lo tanto, escribir su ejemplo utilizando una ArrayList genérica se vería así:

class test<T> { /** It''s not strictly necessary to make this a List vs. an ArrayList You decide what interface you really need to expose internally. */ private List<T> elements; /** This parameter isn''t necessary with a List. You can always call the size() method instead. */ private int size; public test(int size) { this.size = size; elements = new ArrayList<T>(); // Note that the next line isn''t strictly necessary. // An ArrayList can be dynamically resized without any real effort on your part. elements.ensureCapacity(size); } }


Mira también este código:

public static <T> T[] toArray(final List<T> obj) { if (obj == null || obj.isEmpty()) { return null; } final T t = obj.get(0); final T[] res = (T[]) Array.newInstance(t.getClass(), obj.size()); for (int i = 0; i < obj.size(); i++) { res[i] = obj.get(i); } return res; }

Convierte una lista de cualquier tipo de objeto en una matriz del mismo tipo.