How to Instantiate an Inner Class with Reflection in Java

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

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

}

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

}

Java - How to instantiate inner class with reflection?

You need to first access the inner class by doing something like below

// Straightforward parent class initializing
Class<?> cowClass = Class.forName("com.sample.Cow");
Object cowClassInstance = cowClass.newInstance();

// attempt to find the inner class
Class<?> oxClass = Class.forName("com.sample.Cow$Ox");

// Now find the instance of the inner class, you may need to pass in arguments for the constructor
Constructor<?> oxClassContructor = oxClass.getDeclaredConstructor(cowClass);

// initialize the inner instance using the parent class's (cow's) instance
Object oxClassInstance = oxClassContructor.newInstance(cowClassInstance);

Edit

The constructors should look like below

// define the type of args that the constructor requires.
oxClass.getDeclaredConstructor(com.sample.AngusCattle.class, com.sample.ChianinaOx.class);
// now init the constructor with the required args.
Object oxClassInstance = oxClassContructor.newInstance(cowClassInstance, angusCattleClassInstance, chianinaOxClassInstance);

Instantiating inner class

I think you want to declare the HashPerson class as static. Otherwise it can only be instantiated in the context of the containing class, either in a method of the containing class or using code like this:

ContainingClass container = new ContainingClass();
HashPerson william = container.new HashPerson("willy");

Actually, my rule-of-thumb is to make any nested class static, unless I have a special reason not to. This is also more efficient, because non-static nested classes (called inner classes) always contain an implicit reference to the containing object.

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



Related Topics



Leave a reply



Submit