Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to instantiate an inner class with reflection in Java?

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 ?

like image 498
Stephan Avatar asked Jul 05 '13 09:07

Stephan


People also ask

How do you instantiate an inner class in Java?

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax: OuterClass. InnerClass innerObject = outerObject.

How do you access private inner class with reflection?

Accessing the Private Members Write an inner class in it, return the private members from a method within the inner class, say, getValue(), and finally from another class (from which you want to access the private members) call the getValue() method of the inner class.

How do I create an instance of a private inner class?

Yes, you can instantiate a private inner class with Java reflection. To do that, you need to have an instance of outer class and invoke the inner class constructor which will use outer class instance in its first argument. @popgalop Inner classes are the same as methods.

Can we create object using Reflection in Java?

We can use newInstance() method on the constructor object to instantiate a new instance of the class. Since we use reflection when we don't have the classes information at compile time, we can assign it to Object and then further use reflection to access it's fields and invoke it's methods.


1 Answers

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

EDIT: 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() {               // ...           }      } } 
like image 116
Jon Skeet Avatar answered Sep 22 '22 10:09

Jon Skeet