Java范围规则和内部类

dav*_*k01 4 java inner-classes scoping

所有疯狂的Java范围规则都让我头晕目眩,而公共静态无效的废话无助于解决问题.到目前为止,我使用的所有编程语言都是词法作用域或者没有任何访问修饰符的一些近似,即内部东西捕获外部东西,并且只要内部存在东西就可以访问外部东西.

那么我如何理解Java中内部类的作用域规则呢?他们是否可以访问在外部类中声明的变量,或者是否有一些奇怪的边缘情况我不得不担心因为所有公共静态私有东西浮动?

Ted*_*opp 17

静态嵌套类1与外部类完全相同,只是它们可以访问外部类的所有成员,而不管访问限定符.它们存在于外部类的任何实例之外,因此需要引用实例才能访问外部类的任何实例变量或非静态方法.

非静态嵌套类(称为内部类)仅在外部类的实例的上下文中存在.构造时,它们会this自动生成第二个字段,您可以使用语法从内部类中访问它Outer.this.内部类的每个实例都由外部类的单个实例包围.同样,静态嵌套类的所有访问权限都适用于内部类.但由于它们已经有外部类的实例可用,因此它们可以自动访问外部类的实例变量和方法.

有关内部类和访问说明符的精彩(非常详细)讨论,您可以阅读内部类规范.除其他外,它描述了嵌套类如何访问private其外部类的成员.更温和的阅读是嵌套类教程.

偏离主题:假设你有这个类结构:

public class O {
    public O() { ... }

    public class I { // an inner class
        public I() { ... }
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

你已经创建了一个实例O:

O outer = new O();
Run Code Online (Sandbox Code Playgroud)

现在假设您要创建一个实例O.I.你不能只是使用new O.I()因为新的实例I需要被特定的实例包围O.为此,Java提供以下语法:

O.I inner = outer.new O.I();
Run Code Online (Sandbox Code Playgroud)

然后inner将其第二个this字段设置为引用outer.

请注意,此"限定new运算符"语法仅用于内部类; 如果Istatic嵌套类,则不必要(实际上是错误).

1  您经常会遇到"静态内部阶级"这一短语(包括,令人尴尬的是,在此答案的早期版本中).这是不正确的术语.在Java中,"内部类"是特定的非static嵌套类.