我在摆弄java,我创建了两个类,Outer
和Inner
public class Outer {
public class Inner {
}
}
内部类使用默认构造函数。我可以通过调用非参数默认构造函数new Inner()
在Outer
中创建Inner
类的新实例。但是当我尝试使用反射做同样的事情时,我注意到构造函数需要Outer
类型的对象。
是不是意味着内部类的默认构造函数不是非参数?为什么在正常方式调用构造函数和反射之间存在脱节?
没有"以正常方式调用构造函数和反射之间的脱节",只有从Outer
类内部调用构造函数和从Outer
类外部调用构造函数之间的区别。
因为Inner
类不是static
,它有一个对Outer
的引用。如果您想在Outer
之外创建Inner
的实例,您必须这样写:
Outer outerObj = new Outer();
Outer.Inner innerObj = outerObj.new Inner();
向Inner
的构造函数提供outerObj
的要求与通过反射实例化Inner
类的要求完全相同。唯一的区别是语法将outerObj
放在操作符new
的左侧,而反射将outerObj
传递给构造函数。Java编译器将一个隐藏参数添加到它自动生成的构造函数中,就像它将一个隐藏字段添加到生成的类中以保存对Outer
对象的引用一样。
注意,这只适用于非静态内部类。当您的内部类是static
时,没有隐藏参数和隐藏字段,因此反射允许您创建没有Outer
对象的内部类实例。
你的内部类不是静态的,所以你可以创建内部实例只有当你有你的外部对象
我可以通过调用非参数默认构造函数new Inner()在Outer内部创建Inner类的新实例
内部可以,但他不会在外部编译或从Outer
的静态方法编译:
new Outer.Inner();
这是因为当你在Outer
内部调用new Inner()
时,this
被隐式传递给构造函数,这样:
public class Outer {
public class Inner {
}
public example(){
new Inner();
}
}
相当于静态版本:
public class Outer {
public static class Inner {
private Outer mOuter;
public Inner(Outer outer){
mOuter = outer;
}
}
public example(){
new Inner(this);
}
}
对Outer
的隐藏引用允许inner调用Outer
上的方法,就像它们是它自己的一样。