2016-01-05 114 views
13

我想使用一個java switch語句,它使用class名稱作爲case常量。以某種方式可能嗎?還是我必須複製類名?是否有可能在java switch/case語句中使用類名?

下面的代碼不會因爲編譯器錯誤工作:

情況下表達式必須是常量表達式

String tableName = "MyClass1"; 

... 

switch (tableName) { 
case MyClass1.class.getSimpleName(): 
    return 1; 
case MyClass2.class.getSimpleName(): 
    return 2; 
default: 
    return Integer.MAX_VALUE; 
} 

這裏是問題(openjdk 1.8.0_45)的在線演示:http://goo.gl/KvsR6u

+2

你可以嘗試將字符串分配給最終的字符串局部變量嗎? –

+1

哪個java版本?您將在Java 7/8上獲得不同的結果。 – Marged

+0

@已收集我正在使用Java 8,但對任一版本的解決方案感興趣... – dedek

回答

6

編譯器錯誤已經說明了它。案例標籤必須是常量表達式,既不是類文字也不是對它們調用getSimpleName()的結果,它們是常量表達式。

一個可行的解決方案是:

String tableName = "MyClass1"; 
... 
switch (tableName) { 
    case "MyClass1": 
     return 1; 
    case "MyClass2": 
     return 2; 
    default: 
     return Integer.MAX_VALUE; 
} 

表達MyClass1.class.getSimpleName()不超過"MyClass1"簡單,但是,當然,不會有任何編譯時檢查名是否與現有的類和重構工具或混淆器不會注意到類MyClass1和字符串文字"MyClass1"之間的關係。

沒有解決方案。減少問題的唯一方法是在關聯的類中聲明關鍵字以記錄關係,例如,

class MyClass1 { 
    static final String IDENTIFIER = "MyClass1"; 
    ... 
} 
class MyClass2 { 
    static final String IDENTIFIER = "MyClass2"; 
    ... 
} 
... 
String tableName = MyClass1.IDENTIFIER; 
... 
switch (tableName) { 
    case MyClass1.IDENTIFIER: 
     return 1; 
    case MyClass2.IDENTIFIER: 
     return 2; 
    default: 
     return Integer.MAX_VALUE; 
} 

這會記錄與讀者的關係,但工具仍然不能確保實際的字符串內容與類名相匹配。然而,根據你想要達到的目標,現在它可能變得不相關,字符串的內容是否與類名相匹配......

+0

這對我來說是正確的答案:*案例標籤必須是常量表達式,既不是類文字,也不是對其調用'getSimpleName()'的結果,它們是常量表達式* – dedek

+0

**編譯時常量表達式的好解釋**可以在這裏找到:http://stackoverflow.com/a/3827424/1857897 – dedek

+0

我認爲*類文字*是常量表達式,但然後'「」+ MyClass1.class'應該工作,但它不... – dedek

8

而不是使用開關,爲什麼不將映射存儲在地圖中?

創建一個String到Integer的映射,並將所有類名映射到它們的返回值。

對於請求,如果條目不存在,則返回默認值。否則,返回地圖中的值。

+0

我正在考慮這個解決方案,但不會'交換機'更有效率? – dedek

+2

也許吧,但是你的代碼的可讀性也會降低,因爲你需要爲每個類名命名一行,然後爲每個事例添加幾行。你得到的幾納秒的優化可能永遠不值得您使用'Map' –

+1

的代碼的清晰度哦,我忘了補充。如果我沒有記錯,除非最近有什麼變化,否則'在字符串上開關'只是[切換他們的哈希碼](http://www.benf.org/other/cfr/java7switchonstring.html) –

2

而不是Switch..case爲什麼不使用If..Else。應該在所有版本的Java中工作,直到我知道。

if (tableName.equals(MyClass1.class.getSimpleName())) { 
    return 1; 
} else if (tableName.equals(MyClass2.class.getSimpleName())) { 
    return 2; 
} else { 
    return Integer.MAX_VALUE; 
} 
+1

我真的不喜歡'else if'語句,請參閱@ Sam-Sun – dedek

+0

的基於Map的解決方案取決於選擇,但直到我知道這在所有版本中都受支持,您不需要處理任何版本依賴關係。 –

+1

這個解決方案的問題在於,在最壞的情況下,它必須克服每一種可能性,這就是爲什麼人們需要「切換」。 – Leonmax

相關問題