如何在Java中实例化带有反射的非静态内部类?

时间:2022-09-01 17:10:07

I try to instantiate the inner class defined in the following Java code:

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

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

When I try to get an instance of Child like this

当我试图得到这样一个孩子的实例时。

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

I get this exception:

我得到这个例外:

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

What am I missing ?

我错过了什么?

2 个解决方案

#1


103  

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:

有一个额外的“隐藏”参数,它是封闭类的实例。您需要使用类获取构造函数。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);

EDIT: 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() {
              // ...
          }
     }
}

#2


0  

This code create inner class instance.

这段代码创建内部类实例。

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

#1


103  

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:

有一个额外的“隐藏”参数,它是封闭类的实例。您需要使用类获取构造函数。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);

EDIT: 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() {
              // ...
          }
     }
}

#2


0  

This code create inner class instance.

这段代码创建内部类实例。

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