How to Create an Instance of Inner Class Using Java Reflection

How to instantiate an inner class with reflection in Java?

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() {
// ...
}
}
}

Is it possible to create an instance of inner class using Java Reflection?

You need to jump through a few hoops to do this. First, you need to use Class.getConstructor() to find the Constructor object you want to invoke:

Returns a Constructor object that
reflects the specified public
constructor of the class represented
by this Class object. The
parameterTypes parameter is an array
of Class objects that identify the
constructor's formal parameter types,
in declared order. If this Class
object represents an inner class
declared in a non-static context, the
formal parameter types include the
explicit enclosing instance as the
first parameter.

And then you use Constructor.newInstance():

If the constructor's declaring class
is an inner class in a non-static
context, the first argument to the
constructor needs to be the enclosing
instance

How to instantiate an inner class with reflection?

You need to include enclosing classes (ClassA) instance in the constructor as well, since InnerClassA cannot exist without it:

class ClassA {

var iWantToUseThisFromTheInnerClass = "someValue"

fun runThisToStart() {
val classB = ClassB(InnerClassA::class.java)
classB.doSomething(this)

}

inner class InnerClassA(text: String) {
init {
// Log.d("InnerClassA", "Constructor invoked " + text)
}
}

}

class ClassB<T>(private var mModelClass: Class<T>) {

val someText = "whatever"

fun doSomething(enclosingObj : Any):T {
val constructor = mModelClass.getConstructor(enclosingObj::class.java, String::class.java)
return constructor.newInstance(enclosingObj, someText)
}

}

Instantiate private inner class with java reflection

When using reflection, you'll find constructors of that inner class taking an instance of the outer class as an additional argument (always the first) .

See these questions for related information:

  • Instantiating inner class

  • How can I instantiate a member class through reflection on Android

  • In Java, how do I access the outer class when I'm not in the inner class?

Example:

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class OuterClass {

private class InnerClass {

}

public OuterClass() {
super();
}

public static void main(String[] args) {
// instantiate outer class
OuterClass outer = new OuterClass();

// List all available constructors.
// We must use the method getDeclaredConstructors() instead
// of getConstructors() to get also private constructors.
for (Constructor<?> ctor : OuterClass.InnerClass.class
.getDeclaredConstructors()) {
System.out.println(ctor);
}

try {
// Try to get the constructor with the expected signature.
Constructor<InnerClass> ctor = OuterClass.InnerClass.class
.getDeclaredConstructor(OuterClass.class);
// This forces the security manager to allow a call
ctor.setAccessible(true);

// the call
try {
OuterClass.InnerClass inner = ctor.newInstance(outer);
System.out.println(inner);
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

}

Java Reflection to read inner class values

Not sure if I understood the problem, but lets try with a simpler sample:

class TopNode {
public Child1 c1;

public static class Child1 {
public String s1;
}
}

Assuming TN_CONFIG is an instance of TopNode (or any other class that has a c1 which itself has a s1), first we need to get the c1 instance like in

Field fieldC1 = TN_CONFIG.getClass().getDeclaredField("c1");
Object child1 = fieldC1.get(TN_CONFIG);

and then we can can get the field value inside it

Field fieldS1 = fieldC1.getType().getDeclaredField("s1");
Object value = fieldS1.get(child1);

Note: this should also work if Child1 is not a nested class.

Note2: fieldC1.getType() can be replaced by child1.getClass()

invoke inner class method using outer class instance

I think you want too much from reflection, see for example:
Is it possible in java to create 'blank' instance of class without no-arg constructor using reflection?

The following works, but only if you add constructors to the classes. When there are no constructors, I could not get it working:

public class Person
{
public Person(int age)
{
System.out.println("person with age " + age);
}
public void rest(int hours)
{
System.out.println("person rests " + hours);
}
}

public class PersonStoryDerivedTest extends PersonStoryTest {
public PersonStoryDerivedTest()
{
System.out.println("PersonStoryDerivedTest cnstr.");
}
private void thePersonRests(Integer hours) {
person.rest(hours);
}
public void ff(String g){
System.out.println("Alex");
}

public class InnerClass extends PersonStoryTest {
public InnerClass() { System.out.println("InnerClass cnstr."); }
public void aPerson(Integer age) {
person = new Person(age);
}

public void foo(String g){
System.out.println("David");
}
}
}

public class PersonStoryTest
{
public PersonStoryTest()
{
System.out.println("PersonStoryTest cnstr.");
}
Person person;
}

import java.lang.reflect.*;
public class test {
public static void main(String[] args) throws Exception {
PersonStoryDerivedTest a = new PersonStoryDerivedTest();
Method[] g1 = a.getClass().getDeclaredMethods();
g1[1].invoke(a,"fff"); // print Alex (works well)

PersonStoryDerivedTest.InnerClass ab = a.new InnerClass();
Class<?>[] b = a.getClass().getDeclaredClasses();
Method[] g = b[0].getDeclaredMethods();
g[1].invoke(ab,"fff"); // print David (works well)
Constructor<?>[] cs = b[0].getConstructors();
Object o = cs[0].newInstance(a);
g[1].invoke( o ,"fff"); // now works too...
}
}

prints output:

PersonStoryTest cnstr.
PersonStoryDerivedTest cnstr.
Alex
PersonStoryTest cnstr.
InnerClass cnstr.
David
PersonStoryTest cnstr.
InnerClass cnstr.
David


Related Topics



Leave a reply



Submit