2012-11-15 12 views
22

Oto zmienna Class<?> cls, teraz chcę uzyskać kolejny Array Class Object, którego typem komponentu jest cls.o java: pobierz `String []. Class` z` String.class`, a jeśli `String.class` jest" typem środowiska wykonawczego "?

Na przykład, jeśli cls = String.class, chcę uzyskać String[].class; jeśli cls = int.class, chcę uzyskać , co powinienem zrobić?

Widzisz, to dość łatwo dostać String.class z String[].class:

Class<?> arrayCls = String[].class; 
if(arrayCls.isArray()){ 
    Class<?> cls = arrayCls.getComponentType(); 
} 

Ale nie mogę znaleźć łatwy sposób zrobić odwrotnie.

Oto jeden z możliwych rozwiązań:

Class<?> clazz = String.class; 
Class<?> arrayClass = Array.newInstance(clazz,0).getClass(); 

Czy jest jakiś sposób, aby to zrobić ciasto proszę?

+1

Co jest nie tak z tym rozwiązaniem? – Thilo

+0

@Thilo Rozwiązanie jest wynikiem mojego przypuszczenia. Działa dobrze, ale nie jestem pewien, czy to jest najlepszy sposób. To rozwiązanie wymaga dynamicznego utworzenia jednostki tablicowej o długości 0. – watchzerg

+0

Interesujące pytanie. Po prostu ciekawy, dlaczego potrzebujesz tablicy "Class" obiektu? –

Odpowiedz

8

Może spróbuj Class.forName(String)?

Edytuj: Oto fragment kodu.

Class<?> arrayClass = String[].class; 
System.out.println(arrayClass); 
Class<?> namedClass = Class.forName("[L" + String.class.getName() + ";"); 
System.out.println(namedClass); 
System.out.println(arrayClass == namedClass); 
+1

Zgodnie z klasą XMLEncoder w jdk, '' Standard.forName (String) 'jest standardową metodą wykonania tego. Dzięki stary. 'Klasa cls = String.class; Klasa arrayCls = Class.forName ("[L" + cls.getName() + ";"); 'http://stackoverflow.com/questions/4581394/getting-the-class-of-an-dimensional -array-of-an-runtime-provided-class-name – watchzerg

+0

Ah. Zapomniałem o średniku na końcu. – zienkikk

+2

Osobiście wolę twoje rozwiązanie za pomocą 'Array.newInstance'. To przynajmniej wykorzystuje udokumentowane funkcje. Ale przedrostek nazwy '[L' jest wewnętrzną konwencją. W przyszłości mogliby to zmienić i zmienić klasę 'XMLEncoder', ponieważ to także część JDK. To, że coś robi coś w pewien sposób w JDK, nie oznacza, że ​​tak powinieneś to robić, ponieważ piszesz kod aplikacji, a nie kod JDK. – Kidburla

11

Kolejną sztuczką, którą znalazłem jest użycie varargs na metodzie util.

public static void main(String[] args) throws ClassNotFoundException { 

    Class<?> demo = Main.<String>getArrayClass(); 
    System.out.println(demo); 
} 

static <T> Class getArrayClass(T... param){ 
    return param.getClass(); 
} 
+1

Przyjemna sztuczka +1 Właściwie jeśli podasz 'T' na stronie wywołania, nie ma potrzeby przekazywania żadnych argumentów:' MyClass. getArrayClass(); ' –

+0

yes good tip :) Zaktualizowałem! – HRgiger

+4

Dlaczego to nie zwróci klasy 'Object []' za każdym razem z powodu wymazywania typu środowiska wykonawczego? – SpaceTrucker

10

odpowiedź HRgiger poprawiła:

@SuppressWarnings("unchecked") 
static <T> Class<? extends T[]> getArrayClass(Class<T> clazz) { 
    return (Class<? extends T[]>) Array.newInstance(clazz, 0).getClass(); 
} 

oboje instancję obiektu tablicy przy wywołaniu. Aby uzyskać typ tablicy, należy użyć

Class<?> childType = ...; 
Class<?> arrayType = getArrayClass(childType); 
+0

To nie ma nic wspólnego z odpowiedzią HRgigera, jest to poprawa tego, co OP zamieścił w pytaniu. – Holger

+0

Poza tym jestem pewien, że za każdym razem tworzysz tu nowy obiekt, którego nie ma na to druga odpowiedź. –

Powiązane problemy