Alexander Ulyanov
Alexander Ulyanov

Reputation: 33

Java Reflection API. Cant instantiate Inner Class if its not public

Please help me in reflection api. I cant instantiate inner class if it hasnt "public" modifier. I have classes:

public abstract class AbstractClass {
  String str;
    public AbstractClass (String str) {
        this.str = str;
    }
  abstract void process(String str);
}

and

public class Outer {  

  class Inner extends AbstractClass{
    Inner(String str) {
        super(str);
    }

    @Override
    void process(String str) {
        //doSmth
    }
  }
}

And i have method in another place like this:

void fillArray (AbstractClass innerAbstract) {
    try {
        ArrayList<AbstractClass> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Object outerClazz = Class.forName(innerAbstract.getClass().getEnclosingClass().getName()).newInstance();
            Class<?> innerReal = Class.forName(innerAbstract.getClass().getName());
            Constructor<?> ctor = innerReal.getConstructor(outerClazz.getClass(), String.class);
            AbstractClass resultClass = (AbstractClass) ctor.newInstance(outerClazz, innerReal.getName());
            list.add(resultClass);
            resultClass.process("STR");
        }
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException |
            NoSuchMethodException | SecurityException | IllegalArgumentException |
            InvocationTargetException ex) {
        ex.printStackTrace();
    }

}

Inner class - is a realization of AbstractClass. AbstractClass will have a lot of such realizations in different packages and classes.

The question is. All it works fine, when inner classes have public modifier. But it must not be public. When inner classes have public modifier, i can get a list of its constructors with the innerReal.getConstructors().

But when we delete public modifier of Inner - the list of constructors becomes empty. Reflection api lets me to get inner class with its forName() method, but i cant get its instance with the constructor, because it has not any one.

Thanks in advance for any help! =)

Upvotes: 1

Views: 146

Answers (2)

WeMakeSoftware
WeMakeSoftware

Reputation: 9162

You forgot to set constructor as accessible

this should work:

Constructor<?> ctor = innerReal.getConstructor(outerClazz.getClass(), String.class);
ctor.setAccessible(true); // can throw some sort of Exception
AbstractClass resultClass = (AbstractClass) ctor.newInstance(outerClazz, innerReal.getName());

Upvotes: 1

gaborsch
gaborsch

Reputation: 15758

Try getDeclaredConstructors(), it can help you.

Upvotes: 1

Related Questions