嵌套类 -在其他类(包括静态和非静态类)中定义的类
内部类 -非静态嵌套类(内部类的实例需要外部类的实例存在)
非嵌套(顶级)类
根据您的问题,我们知道您要访问的构造函数不是公共的。因此您的班级可能看起来像这样(
A班级与我们的课程有所不同)
package package1;public class A { A(){ System.out.println("this is non-public constructor"); }}要创建此类的实例,我们需要进入要调用的构造函数并使之可访问。完成后,我们可以
Constructor#newInstance(arguments)用来创建实例。
Class<?> c = Class.forName("package1.A");//full package name --------^^^^^^^^^^//or simpler without Class.forName://Class<package1.A> c = package1.A.class;//In our case we need to useConstructor<?> constructor = c.getDeclaredConstructor();//note: getConstructor() can return only public constructors//so we needed to search for any Declared constructor//now we need to make this constructor accessibleconstructor.setAccessible(true);//ABRACADABRA!Object o = constructor.newInstance();嵌套类和内部类
如果要访问嵌套(静态和非静态)类,则
Class.forName需要使用语法:
Class<?> clazz = Class.forName("package1.Outer$Nested");Outer$Nested说
Nested该类是在
Outer类内声明的。嵌套类与方法非常相似,它们可以访问其外部类的所有成员(包括私有成员)。
但是我们需要记住,内部类的实例要存在就需要其外部类的实例。通常,我们通过以下方式创建它们:
Outer outer = new Outer();Outer.Inner inner = outer.new Inner();
因此,如您所见,内部类的每个实例都具有有关其外部类的一些信息(对该外部实例的引用存储在
this$0字段中,
因此,在创建
Inner类实例时,
Constructor#newInstance()您需要将第一个参数引用传递给
Outer类实例(以模拟
outer.newInner()行为)。
这是一个例子。
包装1
package package1;public class Outer { class Inner{ Inner(){ System.out.println("non-public constructor of inner class"); } }}包装2
package package2;import package1.Outer;import java.lang.reflect.Constructor;public class Test { public static void main(String[] args) throws Exception { Outer outerObject = new Outer(); Class<?> innerClazz = Class.forName("package1.Outer$Inner"); // constructor of inner class as first argument need instance of // Outer class, so we need to select such constructor Constructor<?> constructor = innerClazz.getDeclaredConstructor(Outer.class); //we need to make constructor accessible constructor.setAccessible(true); //and pass instance of Outer class as first argument Object o = constructor.newInstance(outerObject); System.out.println("we created object of class: "+o.getClass().getName()); }}静态嵌套类
静态嵌套类的实例不需要Outer类的实例(因为它们是静态的)。因此,在他们的情况下,我们不需要使用
Outer.class第一个参数作为构造函数。而且我们不需要将外部类的实例作为第一个参数传递。换句话说,代码将与非嵌套(顶级)类的代码相同(也许除了您需要在中添加
$Nested语法的事实以外
Class.forName())。



