Pregunta ¿Hay alguna versión genérica de Array.newInstance?


Me di cuenta de que en Java Array.newInstance() devoluciones Object, más bien que T[]. Es comprensible ya que este método se introdujo antes de que Java admita tipos genéricos.

Sin embargo, es una sorpresa que no haya una versión genérica equivalente de esto. Java 7 Arrays.copyOf no es lo mismo: copia el contenido del parámetro, en lugar de crear una nueva matriz ficticia (con todos los objetos nulos dentro).

Dado que la implementación de esto parece trivial, ¿hay alguna razón para no agregarlo al JRE? o simplemente no puedo encontrar uno?

ACTUALIZAR

Parece que voy a proporcionar mi propia implementación "trivial" para dejar de entender mal la pregunta.

class MyArrayUtil {
    //Generic version for classes
    @SuppressWarnings("unchecked")
    public static <T> T[] newArrayOf(T[] t, int len){
        return (T[]) Array.newInstance(t.getClass().getComponentType(), len);
    }
    //For array of int
    public static int[] newArrayOf(int[] t, int len){
        return new int[len];
    }
    //For other primitive types...
}

No estoy publicando este código como respuesta porque no es la respuesta a la pregunta. La pregunta es por motivo y / o código existente, no por cómo implementarlo.

ACTUALIZAR

He actualizado el código para que sea similar a Arrays.copyOf, y la ventaja es que el programador simplemente puede cambiar el tipo de parámetro para ajustar el código para otro tipo. También eliminé el uso de Array.newInstance para tipos primitivos.


8
2017-07-19 02:57


origen


Respuestas:


La guayaba proporciona solo tal función. No es la primera vez que Guava (o Apache Commons) proporciona un ayudante de uso común que el JDK no tiene, por la razón que sea.

Puede que sepas esto, pero algunos antecedentes para el traductor de Google que tropieza con esto en el futuro: la razón por la cual la firma no puede hacerse genérica es que el método Array.newInstance  devuelto Object en Java 1.4, por lo tanto, para compatibilidad con versiones anteriores, la versión sin formato del método también debe devolver Object. Si se hubiera generalizado como:

<T> T[] newInstance(Class<T> componentType, int length)

... entonces el tipo de devolución sería Object[]no Object. Esto rompería la compatibilidad con versiones anteriores, que los diseñadores de Java siempre han intentado no hacer.

los Arrays.copyOf los métodos solo entraron con Java 1.6 y, por lo tanto, no tuvieron que preocuparse por la compatibilidad con versiones anteriores.


7
2017-07-19 05:04



No, debe pasar el tipo concreto como un parámetro de una forma u otra. Como lo mencionaste, Arrays.copyOf muestra esto en acción.

Class<T> type = determinteTheTypeSomehow();
return (T[]) Array.newInstance(type, length);

4
2017-07-19 03:15



La razón básica que Array.newInstance() no puede ser declarado como <T> T[] newInstance(Class<T> class, int size) es porque puede usarse para crear matrices de primitivas. Entonces, por ejemplo, si pasas int.class, que tiene tipo Class<Integer>, luego de la declaración usted esperaría que regresara Integer[] objeto. Sin embargo, la función realmente devuelve un int[] objeto, que no es un subtipo de Integer[], entonces tiene el tipo incorrecto.

Claro, ellos podría agregue un método adicional como newReferenceArrayInstance() que prohíbe los tipos primitivos (por ejemplo, arroja una excepción cuando pasa un tipo primitivo) y, por lo tanto, puede declararse de manera segura para devolver T[]. Sin embargo, eso parece agregar un método completamente redundante únicamente para evitar un lanzamiento no verificado.


3
2017-07-19 22:17