提问者:小点点

隐式引用Java中的封闭类


假设我有一个outer类。 假设有一个非静态成员类inner。 因此,如果outer类声明了inner类型的字段(即根据定义),则outer实例将具有对inner实例的引用。 但是内部实例如何也具有对outer的隐式引用呢? 何时创建此关联?


共3个答案

匿名用户

来自Java语言规范

类O的直接内部类C的实例i与O的实例关联,称为i的直接封闭实例。 在创建对象时,确定对象的直接封闭实例(如果有的话)(§15.9.2)。

匿名用户

你的情况正好相反:

public class Outer {

    void foo() {
        // In this Outer method, we have no implicit instance of Inner.
        innerbar(); // Compiler error: The method bar() is undefined for the type Outer
        Inner.this.innerbar();// Compiler error: No enclosing instance of the type Outer.Inner is accessible in scope

        // instead, one has to create explicitly instance of Inner:

        Inner inner1 = new Inner();
        Inner inner2 = new Inner();

        inner1.innerbar(); // fine!
    }


    class Inner {
        void innerbar() {};

        void callOuter () {
            // But Inner has an implicit reference to Outer.
            callMe();
            // it works also through Outer.this
            Outer.this.callMe();
        }
    }

    void callMe() {}

}

匿名用户

该守则

class Outer {

    class Inner {
        void printOuterThis() {
            System.out.println(Outer.this);
        }
    }

}

Outer.Inner oi = new Outer().new Inner();

大多相当于这个:

class Outer {

    static class Inner {
        Outer outerThis;

        public Inner(Outer outerThis) {
            this.outerThis = outerThis;
        }

        void printOuterThis() {
            System.out.println(outerThis);
        }
    }
}

public class Scratch {
    public static void main(String[] args) {
        Outer.Inner oi = new Outer.Inner(new Outer());
    }
}

编译器自动发出代码,执行第二个字段中发生的操作:隐式引用的字段(this$0,它保存outer.this),转换inner的所有构造函数,并调用它们来添加该字段的初始化。