How to instantiate an inner class with reflection in Java?
Asked Answered
A

2

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 ?

Actomyosin answered 5/7, 2013 at 9:15 Comment(3)
Uhm, your inner class is not static... Is this on purpose? Coming from a C# background maybe? ;)Cumshaw
Thanks for suggesting "static" idea! In fact, using a static nested class instead of an inner class make my life easier.Actomyosin
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.Cumshaw
E
132

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() {
              // ...
          }
     }
}
Ermin answered 5/7, 2013 at 9:18 Comment(4)
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!Athiste
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: #42984797 Thanks!Leopoldeen
so now you have the inner instance how would you call a method of it?Obregon
@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.Ermin
I
-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});
Illimitable answered 17/6, 2017 at 6:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.