ever
ever

Reputation: 83

How to get private inner class instance with reflection in Java?

public class OuterClass {
    private static class InnerClass {
        public int id = 0;
    }
    private static InnerClass[] innerArr;
}

Need to get innerArr value with reflection in Java.

ClassLoader loader = Thread.currentThread().getContextClassLoader();
Class<?> cla = loader.loadClass("OuterClass");
Field innerArrRef = cla.getDeclaredField("innerArr");
innerArrRef.setAccessible(true);    
OuterClass.InnerClass[] innerArrValue = (OuterClass.InnerClass[])innerArrRef.get(cla);

Above code doesn't work for InnerClass is a private class.

Upvotes: 1

Views: 1758

Answers (1)

Erwin Bolwidt
Erwin Bolwidt

Reputation: 31269

Let's adjust your OuterClass code a bit to make it more interesting: put in instance of InnerClass in the array:

private static InnerClass[] innerArr = { new InnerClass() };

Now you can't directly refer to the private type InnerClass in another class that is trying to get the static field using reflection. You can first refer to it as an array of Object.

public static void main(String[] args) throws Exception {
    Class<?> cla = OuterClass.class;
    Field innerArrRef = cla.getDeclaredField("innerArr");
    innerArrRef.setAccessible(true);
    Object[] innerArrValue = (Object[]) innerArrRef.get(cla);

You'll need to use reflection and the Class object to use the InnerClas type.

One way is to use the declaredClasses property of the OuterClass' class object:

    Class<?> inner = cla.getDeclaredClasses()[0];

But if there's more than one member class, you need to loop through the array and search for the right one. Another way is to use the knowledge that javac will give your InnerClass a fully-qualified type name that looks like mypackage.OuterClass$InnerClass:

    Class<?> inner = cla.getClassLoader().loadClass(cla.getName() + "$InnerClass");

Once you have the class object of the InnerClass, you can use reflection to access its field and methods:

    Field id = inner.getField("id");
    System.out.println("Inner id: " + id.getInt(innerArrValue[0]));
}

Upvotes: 3

Related Questions