2013-07-05 7 views
51

Ich versuche, die innere Klasse in dem folgenden Java-Code definiert zu instanziiert:Wie instanziiert innere Klasse mit Reflektion in Java?

public class Mother { 
     public class Child { 
      public void doStuff() { 
       // ... 
      } 
     } 
} 

Wenn ich versuche, diese eine Instanz des Kindes zu bekommen wie

Class<?> clazz= Class.forName("com.mycompany.Mother$Child"); 
Child c = clazz.newInstance(); 

ich diese Ausnahme erhalten:

java.lang.InstantiationException: com.mycompany.Mother$Child 
    at java.lang.Class.newInstance0(Class.java:340) 
    at java.lang.Class.newInstance(Class.java:308) 
    ... 

Was fehlt mir?

+2

Ähm, deine innere Klasse ist nicht statisch ... Ist das Absicht? Kommt vielleicht von einem C# Hintergrund? ;) – fge

+1

Danke für den Vorschlag "statische" Idee! In der Tat macht die Verwendung einer statischen geschachtelten Klasse anstelle einer inneren Klasse mein Leben leichter. – Stephan

+2

Die Sache ist, wenn eine innere Klasse nicht als statisch deklariert wird, Instanzen dieser Klasse von der Existenz einer Instanz der äußeren Klasse abhängen; Dies unterscheidet sich von C#, wobei alle inneren Klassen standardmäßig "statisch" sind und ohne eine übergeordnete Instanz instanziiert werden können. – fge

Antwort

100

Es gibt einen zusätzlichen "versteckten" Parameter, der die Instanz der einschließenden Klasse darstellt. Sie müssen den Konstruktor mithilfe von Class.getDeclaredConstructor aufrufen und dann eine Instanz der umschließenden Klasse als Argument angeben. Zum Beispiel:

// All exception handling omitted! 
Class<?> enclosingClass = Class.forName("com.mycompany.Mother"); 
Object enclosingInstance = enclosingClass.newInstance(); 

Class<?> innerClass = Class.forName("com.mycompany.Mother$Child"); 
Constructor<?> ctor = innerClass.getDeclaredConstructor(enclosingClass); 

Object innerInstance = ctor.newInstance(enclosingInstance); 

EDIT: Alternativ, wenn die verschachtelte Klasse eigentlich nicht brauchen, um eine umgebende Instanz zu verweisen, stellen sie eine verschachtelte statische Klasse statt:

public class Mother { 
    public static class Child { 
      public void doStuff() { 
       // ... 
      } 
    } 
} 
+1

Ich glaube, das eigentliche Problem ist, dass OP nicht bedeutete, dass die Klasse nicht statisch sein sollte, aber ich könnte mich irren – fge

+0

@fge: Möglicherweise. Ich werde das in der Antwort erwähnen. –

+6

Wenn die innere Klasse nicht öffentlich ist, müssen Sie 'ctor.setAccessible (true)' aufrufen, damit es funktioniert! – Beccari

0

Dieser Code erstellen innere Klasseninstanz

Class childClass = Child.class; 
    String motherClassName = childClass.getCanonicalName().subSequence(0, childClass.getCanonicalName().length() - childClass.getSimpleName().length() - 1).toString(); 
    Class motherClassType = Class.forName(motherClassName) ; 
    Mother mother = motherClassType.newInstance() 
    Child child = childClass.getConstructor(new Class[]{motherClassType}).newInstance(new Object[]{mother}); 
Verwandte Themen