【问题标题】:Java Reflection API. Cant instantiate Inner Class if its not publicJava 反射 API。如果不是公共的,则无法实例化内部类
【发布时间】:2015-10-22 11:39:28
【问题描述】:

请在反射 api 中帮助我。如果没有“公共”修饰符,我无法实例化内部类。 我有课:

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

public class Outer {  

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

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

我在另一个地方有这样的方法:

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

}

内部类 - 是 AbstractClass 的一个实现。 AbstractClass 在不同的包和类中会有很多这样的实现。

问题是。当内部类具有 public 修饰符时,一切正常。但不能公开。当内部类有 public 修饰符时,我可以使用 innerReal.getConstructors() 获取其构造函数的列表。

但是当我们删除 Inner 的 public 修饰符时 - 构造函数列表变为空。反射 api 让我可以使用其 forName() 方法获取内部类,但我无法使用构造函数获取其实例,因为它没有任何实例。

提前感谢您的帮助! =)

【问题讨论】:

    标签: java reflection


    【解决方案1】:

    您忘记将构造函数设置为可访问

    这应该可行:

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

    【讨论】:

    • 哦,是的!它对我有帮助!它工作正常!非常感谢! =)
    【解决方案2】:

    试试getDeclaredConstructors(),它可以帮助你。

    【讨论】:

    • 哦!谢谢!真的,我尝试了 getDeclared...() 方法。看来我在尝试中感到困惑=)非常感谢! =)
    • 所以,在我复制简化示例的沙箱中,它工作正常。但在实际项目中,它失败并显示消息:目标 VM 中发生异常:类 ... 无法使用修饰符“”访问 Outer$Inner 类的成员。访问修饰符在示例中是相同的..
    • 在这种情况下,您的生产环境中的SecurityManager 可能会禁止访问。尝试在您的本地环境中重现,并调整SecurityManager,直到找到解决方案。
    猜你喜欢
    • 2017-02-25
    • 2012-12-16
    • 2013-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-24
    相关资源
    最近更新 更多