所有疯狂的 Java 作用域规则都让我头晕目眩,而public static void废话也无济于事。到目前为止,我使用的所有编程语言要么使用词法作用域,要么使用它的一些近似值,而没有任何访问修饰符,即内部东西捕获外部东西,只要内部东西存在,就可以访问外部东西。
那么如何理解 Java 中内部类的作用域规则呢?他们是否可以访问在外部类中声明的变量,或者是否有一些奇怪的边缘情况我必须担心,因为所有公共静态私有的东西都在浮动?
所有疯狂的 Java 作用域规则都让我头晕目眩,而public static void废话也无济于事。到目前为止,我使用的所有编程语言要么使用词法作用域,要么使用它的一些近似值,而没有任何访问修饰符,即内部东西捕获外部东西,只要内部东西存在,就可以访问外部东西。
那么如何理解 Java 中内部类的作用域规则呢?他们是否可以访问在外部类中声明的变量,或者是否有一些奇怪的边缘情况我必须担心,因为所有公共静态私有的东西都在浮动?
静态嵌套类1与外部类完全相同,只是它们可以访问外部类的所有成员,而不管访问限定符如何。它们存在于外部类的任何实例之外,因此需要对实例的引用才能访问外部类的任何实例变量或非静态方法。
非静态嵌套类(称为内部类)仅在外部类实例的上下文中存在。构造时,它们会this
自动生成第二个字段,您可以使用语法从内部类中访问该字段Outer.this
。内部类的每个实例都包含在外部类的单个实例中。同样,静态嵌套类的所有访问权限都适用于内部类。但是由于他们已经有一个可用的外部类的实例,他们可以自动访问外部类的实例变量和方法。
有关内部类和访问说明符的精彩(非常详细)的讨论,您可以通读Inner Class Specification。除其他外,它还描述了嵌套类如何访问private
其外部类的成员。更温和的阅读是嵌套类教程。
题外话:假设你有这样的类结构:
public class O {
public O() { ... }
public class I { // an inner class
public I() { ... }
...
}
...
}
并且您创建了一个实例O
:
O outer = new O();
现在假设您要创建一个O.I
. 您不能只使用new O.I()
,因为新实例I
需要由O
. 为此,Java 提供了以下语法:
O.I inner = outer.new O.I();
然后inner
将其第二个this
字段设置为引用outer
。
请注意,这种“限定new
运算符”语法仅用于内部类;I
如果是static
嵌套类,那将是不必要的(实际上是一个错误) 。
1 您经常会遇到“静态内部类”一词(令人尴尬的是,在此答案的早期版本中)。这是不正确的术语。在 Java 中,“内部类”特别是非static
嵌套类。
你必须区分:
请记住,非静态内部类也有一个带有外部类实例的隐藏变量,以访问那里的成员。并且当内部类被实例化时,所有引用的最终字段(因此它们必须是最终的)被复制到其他隐藏成员变量中的内部类中。
例子:
public void doStuff(final int a, int b) {
final int c; // Can be referenced
int d; // Cannot be referenced, not final
executer.execute( new Runnable() {
public void run() {
System.out.println("a: "+a+" c: "+c);
}
}
b++; // Not final, not referencable
System.out.println(b);
}
我不知道它是否有帮助,但来自java 教程:
静态嵌套类
与类方法和变量一样,静态嵌套类与其外部类相关联。和静态类方法一样,静态嵌套类不能直接引用在其封闭类中定义的实例变量或方法——它只能通过对象引用来使用它们。注意:静态嵌套类与其外部类(和其他类)的实例成员交互,就像任何其他顶级类一样。实际上,静态嵌套类在行为上是一个顶级类,为了方便打包,它已经嵌套在另一个顶级类中。
内部类[非静态嵌套类?]
与实例方法和变量一样,内部类与其封闭类的实例相关联,并且可以直接访问该对象的方法和字段。此外,由于内部类与实例相关联,它本身不能定义任何静态成员。
您应该查看有关嵌套类的 java 教程。
Java内部类的规则
this.x
针对内部 x 和OuterClassname.this.x
外部 x。Outer.Inner ob = new Outer.new Inner();
Outer.Inner ob = new Outer.Inner();
Outer.super.variable;
Outer.super.method(params);
内部类规则
方法作用域内部类:- 只能访问外部类的最终成员。