70

I try to instantiate the inner class defined in the following Java code:

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

When I try to get an instance of Child like this

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

I get this exception:

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

What am I missing ?

Stephan
  • 41,764
  • 65
  • 238
  • 329
  • 3
    Uhm, your inner class is not static... Is this on purpose? Coming from a C# background maybe? ;) – fge Jul 05 '13 at 09:22
  • 1
    Thanks for suggesting "static" idea! In fact, using a static nested class instead of an inner class make my life easier. – Stephan Jul 05 '13 at 10:03
  • 2
    The thing is, if an inner class is not declared static, instances of this class depend on the existence of an instance of the outer class; this is different from C# where all inner classes are "static" by default, and can be instantiated without a parent instance. – fge Jul 05 '13 at 10:08

2 Answers2

131

There's an extra "hidden" parameter, which is the instance of the enclosing class. You'll need to get at the constructor using Class.getDeclaredConstructor and then supply an instance of the enclosing class as an argument. For example:

// 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);

Alternatively, if the nested class doesn't actually need to refer to an enclosing instance, make it a nested static class instead:

public class Mother {
     public static class Child {
          public void doStuff() {
              // ...
          }
     }
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 6
    Just an extra is that if the inner class isn't public, you need to call `ctor.setAccessible(true)` in order to make it work! – Beccari Jun 11 '15 at 17:35
  • 1
    Funny, while walking my dog I thought ... it is so strange, Jon has so many answers, but I rarely run into them when I lookup things. And then ... working on some answer of mine ... I did. And your answer helped me answer some tricky thingy: http://stackoverflow.com/questions/42984297/is-there-any-way-to-instantiate-a-class-defined-in-anonymous-inner-class/ Thanks! – GhostCat Mar 23 '17 at 19:39
  • so now you have the inner instance how would you call a method of it? – Oxnard May 30 '21 at 19:44
  • @Oxnard: That's really not part of this question. You can just call a method as normal, but if you're having problems, ask a new question. – Jon Skeet May 30 '21 at 19:48
-3

This code create inner class instance.

  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});