【问题标题】:How to instantiate an inner class with reflection in Java?如何在 Java 中使用反射实例化内部类?
【发布时间】:2013-07-03 08:17:03
【问题描述】:

我尝试实例化以下 Java 代码中定义的内部类:

 public class Mother {
      public class Child {
          public void doStuff() {
              // ...
          }
      }
 }

当我尝试获取这样的 Child 实例时

 Class<?> clazz= Class.forName("com.mycompany.Mother$Child");
 Child c = clazz.newInstance();

我得到了这个例外:

 java.lang.InstantiationException: com.mycompany.Mother$Child
    at java.lang.Class.newInstance0(Class.java:340)
    at java.lang.Class.newInstance(Class.java:308)
    ...

我错过了什么?

【问题讨论】:

  • 呃,你的内部类不是静态的......这是故意的吗?可能来自 C# 背景? ;)
  • 感谢您提出“静态”的想法!事实上,使用静态嵌套类而不是内部类让我的生活更轻松。
  • 问题是,如果一个内部类没有被声明为静态的,那么这个类的实例依赖于外部类的一个实例的存在;这与默认情况下所有内部类都是“静态”的 C# 不同,并且可以在没有父实例的情况下实例化。

标签: java reflection instantiationexception


【解决方案1】:

还有一个额外的“隐藏”参数,它是封闭类的实例。您需要使用Class.getDeclaredConstructor 获取构造函数,然后提供封闭类的实例作为参数。例如:

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

编辑:或者,如果嵌套类实际上不需要引用封闭实例,请将其改为嵌套 static 类:

public class Mother {
     public static class Child {
          public void doStuff() {
              // ...
          }
     }
}

【讨论】:

  • 我认为真正的问题是 OP 并不意味着课程一开始就不是静态的,但我可能弄错了
  • @fge:可能。我会在答案中提到这一点。
  • 额外的是,如果内部类不公开,您需要调用ctor.setAccessible(true) 才能使其工作!
  • 很有趣,我在遛狗的时候想......这太奇怪了,Jon 有这么多答案,但我在查找内容时很少遇到它们。然后......在我的一些答案上工作......我做到了。你的回答帮助我回答了一些棘手的问题:stackoverflow.com/questions/42984297/… 谢谢!
  • 所以现在你有了内部实例,你将如何调用它的方法?
【解决方案2】:

此代码创建内部类实例。

  Class childClass = Child.class;
  String motherClassName = childClass.getCanonicalName().subSequence(0, childClass.getCanonicalName().length() - childClass.getSimpleName().length() - 1).toString();
  Class motherClassType = Class.forName(motherClassName) ;
  Mother mother = motherClassType.newInstance()
  Child child = childClass.getConstructor(new Class[]{motherClassType}).newInstance(new Object[]{mother});

【讨论】:

    猜你喜欢
    • 2012-12-16
    • 1970-01-01
    • 2014-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多