2009-04-08 9 views
14

Ich habe eine Hilfsmethode und wenn irrelevant Logik von ihm entfernt wird, würde das vereinfachte Verfahren wie folgt aussehen:eine innere Klasse Instanziierungsanwendung

public static <A extends Foo> List<A> getFooList(Class<A> clazz) { 
    List<A> returnValue = new ArrayList<A>(); 
    for(int i=0; i < 5; i++) { 
     A object = clazz.newInstance(); 
     returnValue.add(object); 
    } 

    return returnValue; 
} 

Das Problem ist, dass, wenn clazz eine innere Klasse wie Foo.Bar.class ist , dann die newInstance() Methode wird nicht funktionieren, auch wenn Bar öffentlich wäre, da es eine java.lang.InstantiationException werfen wird.

Gibt es eine Möglichkeit, innere Klassen dynamisch zu instanziieren?

Antwort

27

Wenn es tatsächlich eine inneren Klasse anstatt eine nested (statisch) Klasse, gibt es einen impliziten Konstruktor Parameter, der die Referenz auf die Instanz der äußeren Klasse ist. Sie können Class.newInstance zu diesem Zeitpunkt nicht verwenden - Sie müssen den entsprechenden Konstruktor erhalten. Hier ein Beispiel:

import java.lang.reflect.*; 

class Test 
{ 
    public static void main(String[] args) throws Exception 
    { 
     Class<Outer.Inner> clazz = Outer.Inner.class; 

     Constructor<Outer.Inner> ctor = clazz.getConstructor(Outer.class); 

     Outer outer = new Outer(); 
     Outer.Inner instance = ctor.newInstance(outer); 
    } 
} 

class Outer 
{ 
    class Inner 
    { 
     // getConstructor only returns a public constructor. If you need 
     // non-public ones, use getDeclaredConstructors 
     public Inner() {} 
    } 
} 
0

Diese Ausnahme wird nur ausgelöst, wenn clazz entweder eine abstrakte Klasse oder eine Schnittstelle darstellt. Sind Sie sicher, dass Sie ein Klassenobjekt übergeben, das eine konkrete Klasse darstellt?

5

Etwas mehr generic:

public static <T> T createInstance(final Class<T> clazz) throws SecurityException, NoSuchMethodException, 
      IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException { 

      T instanceToReturn = null; 
      Class<?> enclosingClass = clazz.getEnclosingClass(); 

      if (enclosingClass != null) { 
       Object instanceOfEnclosingClass = createInstance(enclosingClass); 

       Constructor<T> ctor = clazz.getConstructor(enclosingClass); 

       if (ctor != null) { 
        instanceToReturn = ctor.newInstance(instanceOfEnclosingClass); 
       } 
      } else { 
       instanceToReturn = clazz.newInstance(); 
      } 

      return instanceToReturn; 
    } 
+0

Sie müssen noch, wenn die innere Klasse nicht statisch zu überprüfen, ist ... – Corin

Verwandte Themen