[英]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.