内部类的默认构造函数需要外部类对象吗?

4

我在尝试Java编程时,创建了两个类,OuterInner

public class Outer {
    public class Inner { 
    }
}

内部类使用默认构造函数。在Outer内部调用非参数默认构造函数new Inner()就可以创建一个新的Inner类实例。但是当我尝试使用反射做同样的事情时,我注意到构造函数需要Outer类型的对象。

这是否意味着内部类的默认构造函数不是非参数的?为什么在正常调用构造函数和反射中存在差异?

3个回答

4

在正常方式和反射方式下调用构造函数并没有“不连续的”,只有在从Outer类内部和Outer类外部调用构造函数之间才存在不连续。

由于Inner类不是static,它引用了Outer。如果你想要在Outer外部创建一个Inner实例,你必须像这样写:

Outer outerObj = new Outer();
Outer.Inner innerObj = outerObj.new Inner();

提供outerObjInner构造函数的要求与通过反射实例化Inner类时完全相同。唯一的区别是语法将outerObj放在new操作符左侧,而反射将outerObj传递给构造函数。Java编译器会自动生成一个隐藏参数添加到构造函数中,以相同的方式生成一个隐藏字段来保存对Outer对象的引用。
请注意,这仅适用于非静态内部类。当您的内部类是static时,没有隐藏参数和隐藏字段,因此反射允许您创建内部类的实例而不需要Outer对象。

1

你的内部类不是静态的,因此只有在拥有外部对象时才能创建内部实例。


1
我可以通过调用非参数默认构造函数new Inner()在Outer内创建Inner类的新实例。 但是,在Outer之外或从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的引用允许内部调用Outer的方法,就像它是自己的一样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接