[英]Method local inner class vs inner class
下面的代码生成输出middle
。 谁能详细解释这是怎么回事?
是因为class A
的“内部”版本的声明是在go()
方法中创建class A
的实例之后发生的吗?
class A {
void m() {
System.out.println("outer");
}
}
public class MethodLocalVSInner {
public static void main(String[] args) {
new MethodLocalVSInner().go();
}
void go() {
new A().m();
class A {
void m() {
System.out.println("inner");
}
}
}
class A {
void m() {
System.out.println("middle");
}
}
}
inner
不打印的原因是( 6.3 ):
由块直接包含的本地类声明的范围是直接封闭块的其余部分,包括它自己的类声明。
(在方法内声明的类称为本地类。)
所以A
不能引用本地类,因为表达式new A()
在声明之前发生。 换句话说,本地类与局部变量具有相似的范围。
middle
打印而不是outer
的原因是内部类A
影响顶级类A
( 6.4.1 ):
的声明
d
命名类型的n
阴影任何其他类型的命名的声明n
是在范围[...]的d
。
这意味着MethodLocalVSInner
正文中的任何位置,非限定A
必须引用内部类。
如果您熟悉成员变量的阴影,例如:
class Example {
int x;
void setX(int x) {
// ┌ 'x' refers to the local method parameter
this.x = x;
}
}
基本上同样的事情是继续进行类声明。
情况1:
void go() {
new A().m();
class A {
void m() {
System.out.println("inner");
}
}
}
在这种情况下,如果您在本地类的范围之外运行您的方法。 这就是它打印middle
案例2:
void go() {
class A {
void m() {
System.out.println("inner");
}
}
new A().m();
}
在这种情况下,它将打印inner
becase类现在在范围内。
在方法中:
void go() {
new A().m();
class A {
void m() {
System.out.println("inner");
}
}
}
当方法开始执行时,第一行将执行new A().m();
并且因为内部类已经在范围内,所以将创建该类的对象,并且将为inner class
调用m
方法而不是local method class
因为它仍然不在范围内。 这就是为什么你得到middle
作为输出。
但如果您将方法更改为:
void go() {
class A {
void m() {
System.out.println("inner");
}
}
new A().m();
}
您的本地方法类现在将在范围内并具有更高的首选项,因此您现在将获得输出inner
。
您正在使用MethodLocalVSInner
的实例调用go
方法
在go方法中你要创建一个A()
实例,因为你没有显式地导入外部A class
而直接内部类是在方法调用语句之后,JVM正在选择MethodLocalVSInner
类级别的inner class A
并在其中执行go方法
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.