Ram*_*tra 44 java inner-classes
以下代码生成输出middle.谁能详细解释这是怎么回事?
是因为声明"内部"版本class A来自在方法中class A创建的实例之后go()?
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");
}
}
}
Run Code Online (Sandbox Code Playgroud)
Roh*_*ain 38
我猜你期望调用本地类方法.这没有发生,因为你在new A()本地范围之外使用.因此,它访问范围中的下一个更接近的候选者,即内部类.来自JLS§6.3:
由块(第14.2节)直接包含的本地类声明的范围是直接封闭块的其余部分,包括它自己的类声明.
因此,new A()在第一行方法中,将不会访问出现在它之后的本地类.如果在此之前移动类声明,您将获得预期的输出.
另请参阅JLS§14.3,其中包含类似示例.
Tim*_*sen 17
由于您拥有代码的顺序,您将获得输出"中间".由于方法范围class A发生在您的调用之后new A(),您将获得输出"中间".如果您按如下方式切换订单,您将获得输出"内部":
void go() {
class A {
void m() {
System.out.println("inner");
}
}
new A().m();
}
Run Code Online (Sandbox Code Playgroud)
输出:
inner
实例化的优先顺序,class A从高到低,是:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
基本上同样的事情是继续进行类声明.