Java 作用域规则和内部类
所有疯狂的 Java 作用域规则都让我头晕目眩,而 public static void 的废话对事情没有帮助。到目前为止,我使用的所有编程语言都使用了词法作用域或它的某种近似值,而没有任何访问修饰符,即内部内容捕获外部内容,并且只要内部内容存在就可以访问外部内容。
那么如何理解 Java 中内部类的作用域规则呢?他们是否可以访问外部类中声明的变量,或者是否有一些奇怪的边缘情况我必须担心,因为所有公共静态私有的东西浮动?
All the crazy Java scoping rules are making my head spin and the public static void nonsense isn't helping matters. So far all the programming languages I have used either lexical scoping or some approximation of it without any access modifiers, i.e. inner stuff captures outer stuff and has access to the outer stuff as long as the inner stuff exists.
So how do I make sense of the scoping rules for inner classes in Java? Do they get access to variables declared in the outer class or is there some weird edge cases I have to worry about because of all the public static private stuff floating around?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
静态嵌套类1与外部类完全相同,只是它们可以访问外部类的所有成员,而不管访问限定符如何。它们独立于外部类的任何实例而存在,因此需要对实例的引用才能访问外部类的任何实例变量或非静态方法。
非静态嵌套类(称为内部类)仅在外部类实例的上下文中存在。构造时,它们会自动生成第二个
this
字段,您可以使用语法Outer.this
从内部类中访问该字段。内部类的每个实例都包含在外部类的单个实例中。同样,静态嵌套类的所有访问权限都适用于内部类。但由于它们已经有了可用的外部类的实例,因此它们可以自动访问外部类的实例变量和方法。有关内部类和访问说明符的精彩(且非常详细)的讨论,您可以阅读 内部类规范。除其他外,它还描述了嵌套类如何访问其外部类的私有成员。更温和的阅读是嵌套类教程。
题外话:假设您有这样的类结构:
并且您已经创建了
O
的实例:现在假设您想要创建
OI
的实例。您不能只使用new OI()
,因为I
的新实例需要包含在O
的特定实例中。为此,Java 提供了以下语法:然后
inner
将其第二个this
字段设置为引用outer
。请注意,这种“限定 new 运算符”语法仅用于内部类;如果
I
是一个static
嵌套类,则没有必要(事实上,这是一个错误)。1 您经常会遇到“静态内部类”这个短语(令人尴尬的是,包括在这个答案的早期版本中)。这是不正确的术语。在 Java 中,“内部类”特指非
静态
嵌套类。Static nested classes1 are exactly like external classes except that they have access to all members of the outer class, regardless of access qualifier. They exist apart from any instance of the outer class, so need a reference to an instance in order to access any instance variables or non-static methods of the outer class.
Non-static nested classes (called inner classes) come into existence only in the context of an instance of the outer class. When constructed, they have a second
this
field automatically generated, which you can access from within the inner class using the syntaxOuter.this
. Each instance of the inner class is enclosed by a single instance of the outer class. Again, all the access privileges of static nested classes apply to inner classes. But since they already have an instance of the outer class available, they can automatically access instance variables and methods of the outer class.For a nice (and very detailed) discussion of inner classes and access specifiers, you can read through the Inner Class Specification. It describes, among other things, how a nested class gets access to
private
members of its outer class(es). A gentler read is the Nested Classes tutorial.An off-topic aside: Suppose you have this class structure:
and you've created an instance of
O
:Now suppose you want to create an instance of
O.I
. you can't just usenew O.I()
because the new instance ofI
needs to be enclosed by a specific instance ofO
. For this, Java provides the following syntax:Then
inner
will then have its secondthis
field set to refer toouter
.Note that this "qualified
new
operator" syntax is only used for inner classes; it would be unnecessary (in fact, an error) ifI
were astatic
nested class.1 You'll often come across the phrase "static inner class" (including, embarrassingly, in an earlier version of this answer). This is incorrect terminology. In Java, "inner classes" are specifically non-
static
nested classes.您必须区分:
请记住,非静态内部类还具有实例的隐藏变量外部类的,访问那里的成员。并且当内部类实例化时,所有引用的最终字段(因此它们必须是最终的)都会被复制到内部类的其他隐藏成员变量中。
例子:
You have to differenciate:
Have in mind that a non-static inner class also has a hidden variable with the instance of the outer class, to access the members there. And that all referenced final fields (therefore they must be final) are copied into the inner class in other hidden member variables when the inner class is instantiated.
Example:
我不知道它是否有帮助,但是来自 java 教程:
您应该查看有关嵌套类的 Java 教程。
I don't know if it helps, but from the java tutorials:
You should check the java tutorial on nested classes.
Java 中内部类的规则
this.x
for内部 x 和外部 x 的OuterClassname.this.x
。Outer.Inner ob = new Outer.new Inner();
Outer.Inner ob = new Outer.Inner();
Outer.super.variable;
Outer.super.method(params);
Rules of the Inner classes in Java
this.x
for the inner x andOuterClassname.this.x
for the outer x.Outer.Inner ob = new Outer.new Inner();
Outer.Inner ob = new Outer.Inner();
Outer.super.variable;
Outer.super.method(params);
内部类规则
Rules for inner class
方法作用域内部类:-
只能访问外部类的final成员。
Method Scoped inner classes:-
Can only access the final members of the outer class.