简体   繁体   English

隐式引用Java中的封闭类

[英]Implicit reference to an enclosing class in Java

Lets say I have a Outer class. 可以说我有一个Outer班。 Lets say there is a non static member class Inner . 可以说有一个非静态成员类Inner So an Outer instance will have a reference to an instance of Inner if the Outer class declares a field of type Inner and that is by definition. 因此,如果Outer类声明了Inner类型的字段(根据定义),则Outer实例将引用Inner实例。 But how does Inner instance also has a implicit reference to Outer ? 但是Inner实例又如何隐式引用Outer呢? When is this association created? 该关联何时创建?

From the Java language Spec Java语言规范

An instance i of a direct inner class C of a class O is associated with an instance of O, known as the immediately enclosing instance of i. O类的直接内部类C的实例i与O实例相关联,称为i的直接封闭实例。 The immediately enclosing instance of an object, if any, is determined when the object is created (§15.9.2). 创建对象时立即确定对象的直接封闭实例(第15.9.2节)。

You have it the other way around: 反过来,您也可以使用它:

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() {}

}

The code 编码

class Outer {

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

}

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

is mostly equivalent to this: 大致等于:

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

The compiler automatically emits code that does what happens in the second: a field ( this$0 that holds the value of Outer.this ) for the implicit reference and transforms all constructors of Inner and calls to them to add initialisation of this field. 编译器自动发出执行第二步操作的代码:隐式引用的字段( this$0持有Outer.this的值),并转换Inner所有构造函数,并对其进行调用以添加此字段的初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM