web-dev-qa-db-fra.com

Comment instancier une classe interne avec réflexion en Java?

J'essaie d'instancier la classe interne définie dans le code Java Java:

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

Quand j'essaye d'obtenir une instance de Child comme ça

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

Je reçois cette exception:

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

Qu'est-ce que je rate ?

61
Stephan

Il y a un paramètre "caché" supplémentaire, qui est l'instance de la classe englobante. Vous devrez accéder au constructeur en utilisant Class.getDeclaredConstructor , puis fournissez une instance de la classe englobante comme argument. Par exemple:

// 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: Alternativement, si la classe imbriquée n'a pas réellement besoin de faire référence à une instance englobante, faites-en plutôt une classe imbriquée statique :

public class Mother {
     public static class Child {
          public void doStuff() {
              // ...
          }
     }
}
113
Jon Skeet