[英]Not coherent behaviour in switch-case statement in Java7 and Java8
我正在准備Java7 Oracle證書,並且想知道為什么Java以這種奇怪的方式處理切換情況:
public static void main(String[] args) {
int a = 2;
switch (a) {
case 0:
//System.out.println(b); // cannot find symbol variable b
break;
case 1:
boolean b=false;
break;
case 2:
b = true; // how case knows about existence of variable b?
break;
case 3:
//System.out.println(b); // var b might not have been initialized
break;
}
}
這很明顯為什么情況0和情況3會通知未知符號或未初始化的變量,但是我無法想象為什么情況2可以正常工作? 如果b
在情況1中被分配,編譯器如何得知b
的類型? 對我而言,這並不連貫。
UPDATE1:實際上,更奇怪的是,在情況3中,我注意到編譯時錯誤(Linux64,Java7和Java8),但是我的一些同事卻沒有。
我准備了一個非常簡單的Maven項目: https : //github.com/gonciarz/switch-test
UPDATE2:似乎對每個案例case3都不編譯。 謝謝你們的澄清。
您正在混合聲明和賦值。 在你的代碼中
case 1:
boolean b=false;
break;
case 2:
b = true; // how case knows about existence of variable b?
break;
在case 1:
聲明和分配變量b
。 聲明的范圍是switch
語句塊的其余部分,即直到}
為止。
就像您寫過的一樣:
case 1:
boolean b;// declaration
b=false; // assignment
break;
分配對case 2:
標簽的代碼流無效。 如果發生跳轉到case 2
標簽,則聲明變量但未分配該變量,因為可以跳過一個賦值但不能聲明。
因此,該行為與您的第三個標簽一致:
case 3:
System.out.println(b); // var b might not have been initialized
break;
在此, 聲明了變量b
,但未賦值 。 這就是錯誤消息告訴您的內容:它不是說未聲明b
,而是“可能尚未初始化”,其中包括您肯定知道它尚未被初始化的可能性。
b
的類型是聲明的類型,並且不依賴於任何賦值。
作為附帶說明, switch
和if
之間有區別。 你寫了嗎
final int a = 2;
boolean b;
if(a == 2) b=false;
System.out.println(b);
的恆定性質a
引起編譯器來檢測b
將被分配到false
且沒有產生錯誤。 這適用於if
但不適用於switch
。
您的范圍是整個switch子句,而不是單獨的情況。 范圍由{
和}
定義。
當使用boolean b = false
聲明變量時,可以在范圍的其余部分(即switch子句的其余部分)中訪問它。
您在問題中提到的情況3不會出錯。
編輯:在情況3中確實會出現錯誤,但是Eclipse在檢測它時似乎很草率。 我將字段聲明與原始變量的默認值與沒有的局部變量混淆了。
規則說:
塊中的局部變量聲明的范圍(第14.4節)是該聲明在其中出現的其余部分,從其自身的初始化程序開始,並在該局部變量聲明語句的右側包括其他任何聲明符。
和這個
聲明在編譯時處理,並且不依賴於代碼的執行流程。 由於value是在switch塊的局部范圍內聲明的,因此從聲明的位置開始,該值可在該塊中的任何位置使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.