所有疯狂的Java范围规则都让我头疼, public static void 废话无济于事。到目前为止,我使用的所有编程语言都是词法范围或者没有任何访问修饰符的一些近似,即内部东西捕获外部东西,并且只要内部东西存在就可以访问外部东西。
那么我如何理解Java中内部类的作用域规则?他们是否可以访问在外部类中声明的变量,或者是否有一些奇怪的边缘情况我不得不担心因为所有公共静态私有的东西浮动?
答案 0 :(得分:17)
静态嵌套类 1 与外部类完全相同,只是它们可以访问外部类的所有成员,而不管访问限定符。它们存在于外部类的任何实例之外,因此需要引用实例才能访问外部类的任何实例变量或非静态方法。
非静态嵌套类(称为内部类)仅在外部类的实例的上下文中存在。构造时,它们会自动生成第二个this
字段,您可以使用语法Outer.this
从内部类中访问该字段。内部类的每个实例都由外部类的单个实例包围。同样,静态嵌套类的所有访问权限都适用于内部类。但由于它们已经有外部类的实例,它们可以自动访问外部类的实例变量和方法。
有关内部类和访问说明符的讨论(非常详细),您可以阅读Inner Class Specification。除其他外,它描述了嵌套类如何访问其外部类的private
成员。温和的阅读是Nested Classes tutorial。
偏离主题:假设你有这个类结构:
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
嵌套类。
答案 1 :(得分:3)
你必须区分:
请记住,非静态内部类还有一个隐藏变量和外部类的实例,以访问那里的成员。并且在实例化内部类时,所有引用的最终字段(因此它们必须是最终字段)将被复制到其他隐藏成员变量的内部类中。
示例:
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);
}
答案 2 :(得分:3)
我不知道它是否有帮助,但来自java tutorials:
静态嵌套类
与类方法和变量一样,静态嵌套类与其外部类相关联。和静态类方法一样,静态嵌套类不能直接引用其封闭类中定义的实例变量或方法 - 它只能通过对象引用来使用它们。 注意:静态嵌套类与其外部类(和其他类)的实例成员交互,就像任何其他顶级类一样。实际上,静态嵌套类在行为上是一个顶级类,它已嵌套在另一个顶级类中以方便打包。
内部类 [非静态嵌套类?]
与实例方法和变量一样,内部类与其封闭类的实例相关联,可直接访问该对象的方法和字段。此外,因为内部类与实例相关联,所以它本身不能定义任何静态成员。
答案 3 :(得分:1)
Java中内部类的规则
this.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);
答案 4 :(得分:0)
内部类规则
答案 5 :(得分:-1)
方法范围内部类: - 只能访问外部类的最终成员。