2010-11-05 40 views
9

我最近添加了另一個菜單項到一個android java應用程序,很驚訝,Eclipse說,從前面的情況變量:break不是本地的(所以我剛剛添加了一個後綴通過)。爲什麼變量在case語句中不是局部的?

我有點困惑,因爲在我的腦海裏,第一套案例:如果第二個選項被選中,break將不會被執行。有人能解釋我錯誤的想法嗎?

 case R.id.menuDebugMode: 
      debugMode = !debugMode; 
      if (debugMode){ 
       Toast.makeText(mainActivity.this, "Debug Mode on - NOT TO BE USED WHILST DRIVING", Toast.LENGTH_LONG).show();   
      } else { 
       tvDebug.setText(""); 
       tvInfo.setText(""); 
      } 
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); 
      SharedPreferences.Editor editor = settings.edit(); 
      editor.putBoolean("debugMode", debugMode); 
      editor.commit(); 
     break; 

     case R.id.menuSpeedMode: 
      speedSignMode = !speedSignMode; 
      if (speedSignMode){ 
       Toast.makeText(mainActivity.this, "SpeedSign Mode in use", Toast.LENGTH_LONG).show();   

      } else { 
        Toast.makeText(mainActivity.this, "MapSpeed Mode in use", Toast.LENGTH_LONG).show();    
      } 
      SharedPreferences settings2 = getSharedPreferences(PREFS_NAME, 0); 
      SharedPreferences.Editor editor2 = settings2.edit(); 
      editor2.putBoolean("speedSignMode", speedSignMode); 
      editor2.commit(); 
     break;` 
+0

感謝所有快速和有用的答案 - 我將TME標記爲可接受的答案(因爲它具有清晰的原因:)但所有答案都是好的答案。我通常是一個如果然後elseif類型的程序員,所以這就是爲什麼我被抓到這裏:) – SimpleSi 2010-11-05 09:29:52

回答

9

與C中一樣,在Java中,switch語句並不是人們在查看時所期望的。該簡化使得很難理解範圍未被創建。這一切都歸結爲C,其中開關只是語法糖。編譯器將開關轉換爲多個條件跳轉。這使得語言可以使用貫穿式,這是在設計C期間的特徵(「中斷」仍然是可選的)。這個Java功能C.

保持兼容
switch(a): 
    case 1: 
     dosomething(); 
    case 2: 
     dosomemore(); 

被翻譯成

if(a==1) jump ##1; 
if(a==2) jump ##2; 
jump ##3; 
##1: 
dosometing(); 
##2: 
dosomemore(); 
##3: 
12

你說得對,最多一個人會執行,但一個案例不會創建一個新的範圍。您可以使用自己的作用域手動創建塊。

case foo: 
    { 
     int var = ... 
    } 
    break; 

case bar: 
    { 
     int var = ... 
    } 
    break; 
+2

@Dave,這只是明顯錯誤。 break語句停止執行下一個case語句。 – SimonC 2010-11-05 07:43:41

3

Matthew是正確的 - 整個switch語句對於任何直接在其中聲明的變量都有一個範圍。根據馬修的回答,你可以可以增加更多的大括號 - 但是將它們作爲方法提取出來幾乎肯定會更好。看起來他們正在做的很多事情就像這樣被「內聯」包含在內。

請注意,這裏的範圍規則並不是特定於Android--它們是Java的範圍規則。

1

因爲你不應該寫那麼多的代碼/邏輯 - 把它們分解成方法。

4

其他人解釋你應該做的,並認爲這是一個Java語言的事情,而不是一個Android具體的事情。

至於爲什麼 Java語言是這樣定義的,我還沒有想出一個完全合乎邏輯的理由。我能想到的最好的是,如果每一個switch語句的病例列表的隱式定義的範圍,那麼下面很容易被誤讀:

case foo: 
    int var = ... 
    // note drop through 
case bar: 
           int var = ... 
    var = var + 1; 
    break; 

至少與作用域的當前定義,所有的可能令人困惑的用法會導致編譯錯誤。 (國際海事組織,它會更好地避開switch語句中的情況下降,就像C#所做的那樣,但是這樣的設計錯誤在事後看來更容易發現,並且一旦產生就很難糾正。 )

1

在additon其他答案:這裏是來自java language definition的解釋:

每當控制的流進入塊 [...],爲每個局部變量來創建一個新變量在立即包含在該塊內的局部變量聲明語句中聲明[...]局部變量有效在執行塊[[...]時不再存在]已完成

局部變量作用域是塊({ ... }),其中包括內部塊。代碼中的實際塊是從switch聲明開始的塊。

相關問題