Ottenere la matrice Classe di un tipo di componente

Se ho un’istanza di Class , c’è un modo per ottenere un’istanza di Class per il suo tipo di array? Quello che sto essenzialmente chiedendo è l’equivalente di un metodo getArrayType che è l’inverso del metodo getComponentType() , tale che:

 array.getClass().getComponentType().getArrayType() == array.getClass() 

Una cosa che viene in mente è:

 java.lang.reflect.Array.newInstance(componentType, 0).getClass(); 

Ma crea un’istanza non necessaria.

A proposito, sembra funzionare:

 Class clazz = Class.forName("[L" + componentType.getName() + ";"); 

Ecco il test. Stampa true :

 Integer[] ar = new Integer[1]; Class componentType = ar.getClass().getComponentType(); Class clazz = Class.forName("[L" + componentType.getName() + ";"); System.out.println(clazz == ar.getClass()); 

La documentazione di Class#getName() definisce rigorosamente il formato dei nomi di class dell’array:

Se questo object di class rappresenta una class di matrici, la forma interna del nome è costituita dal nome del tipo di elemento preceduto da uno o più caratteri [[‘] che rappresentano la profondità del nidificazione di array.

L’ Class.forName(..) non funzionerà direttamente con le primitive, ma per loro dovresti creare una mapping tra il nome ( int ) e l’array stenografia – ( I )

In realtà a causa di ClassLoader , primitive e array multidimensionali, la risposta è un po ‘più complessa:

 public static Class getArrayClass(Class componentType) throws ClassNotFoundException{ ClassLoader classLoader = componentType.getClassLoader(); String name; if(componentType.isArray()){ // just add a leading "[" name = "["+componentType.getName(); }else if(componentType == boolean.class){ name = "[Z"; }else if(componentType == byte.class){ name = "[B"; }else if(componentType == char.class){ name = "[C"; }else if(componentType == double.class){ name = "[D"; }else if(componentType == float.class){ name = "[F"; }else if(componentType == int.class){ name = "[I"; }else if(componentType == long.class){ name = "[J"; }else if(componentType == short.class){ name = "[S"; }else{ // must be an object non-array class name = "[L"+componentType.getName()+";"; } return classLoader != null ? classLoader.loadClass(name) : Class.forName(name); } 

Puoi fare quanto segue

 array.getClass() == Array.newInstance(array.getClass().getComponentType(), 0).getClass() 

Di solito, non è necessario conoscere il tipo, si desidera solo creare l’array.

Un altro ansible refactoring consiste nell’utilizzare una superclass generica e passare in class due oggetti al costruttore.

 protected AbstractMetaProperty(Class valueClass, Class valueArrayClass) { this.valueClass = valueClass; this.valueArrayClass = valueArrayClass; } 

Quindi in sottoclassi:

 public IntegerClass() { super(Integer.class, Integer[].class); } 

Quindi nella class astratta puoi usare valueClass.cast(x) , valueArrayClass.isInstance(x) ecc.