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
Does the Preparedstatement Avoid SQL Injection
How to Hide Cursor in a Swing Application
Should I Retrieve Database Record in Struts2 View Layer
Shuffle a List of Integers with Java 8 Streams API
How to Send List of Objects to View and Back to Post Method in Controller
Javax.Mail.Authenticationfailedexception Is Thrown While Sending Email in Java
Attach the Source in Eclipse of a Jar
How Pause and Then Resume a Thread
Java Import VS Code Performance
What Is the Actual Memory Place for Static Variables
Determine If a Java Application Is in Debug Mode in Eclipse
How to Unit Test Abstract Classes: Extend with Stubs
How to Run a Class from Jar Which Is Not the Main-Class in Its Manifest File
Java "" Operator for Checking Null - What Is It? (Not Ternary!)
Javafx Exception in Thread "Main" Java.Lang.Noclassdeffounderror: Javafx/Application/Application