2011-12-30 43 views
4

我無法找出Java中交換機的內部工作原理 我被告知,對於所有原語,該值都被提升爲整數。在Java中切換非Ints

然而,在下面的例子中,我測試一個字節變量,任何情況下大於127不會編譯:

byte k = 5; 
switch(k){ 
    case 128: //fails to compile, possible loss of precision 

我意識到這是一個錯誤,沒有任何問題,這一點。我的問題是:
JVM如何跟蹤它在一個字節上的切換,如果它在測試每個個案之前將值「k」提升爲一個整數?

+0

我不關心編譯錯誤,這只是一個例子。開關變量是否被提升爲整數? – Adam 2011-12-30 21:17:07

+0

它被提升,請參閱我的答案或JVM規範第7.10節 – 2011-12-30 21:34:41

回答

3

問題是它沒有提升k的值,它試圖將case語句(128 - 有符號整數)並將其分配給一個字節。由於128大於1個字節(7位+符號位),編譯失敗。

例如

byte k = 128; 

也將編譯失敗。 見Java Language Specification

+0

我意識到那一部分。我的問題是,如果被切換的值被提升爲一個整數,那麼JVM如何跟蹤真正的類型是什麼類型 – Adam 2011-12-30 21:25:18

+0

正在切換的值(例如k)不會被提升爲整數,而是會嘗試使用大小寫常量被解釋爲要切換的值的類型(例如字節)。 (這是有道理的嗎?) – Charlie 2011-12-30 21:28:39

+0

你是說,如果不知何故值變成了一個整數?哪些不會發生,因爲你已經將它定義爲一個字節? – Charlie 2011-12-30 21:32:30

2

它不編譯因爲:

類型不匹配:不能從int轉換爲字節

這是顯而易見的,因爲你的k爲byte類型和文字128是一個int按照Java規則。

如果更改case語句:

case (byte) 128: 

那麼它將編譯沒有任何錯誤。

0

字節的大小隻有-128到127。當你傳遞字節作爲開關的情況下,它是精度丟失並突出顯示編譯時間所需的字節,發現int錯誤。字節(128)將解決問題。

+1

字節是-128到127 – Charlie 2011-12-30 21:11:38

+0

無論如何這是錯誤的答案......'字節'不被提升。 – Paul 2011-12-30 21:12:30

+0

@Charlie,更新了我的答案。謝謝 – kosa 2011-12-30 21:13:27

1

你只需要轉換爲byte

switch(k) { 
    case (byte) 128: 
} 

這很好 - 問題只是,有沒有從字面128 byte的隱式轉換。你用簡單的分配同樣的問題:

// Invalid 
byte a = 128; 

// Valid 
byte b = (byte) 128; 

b值將實際上是-128,因爲128是一個Java byte的範圍之外 - 而比特模式是正確的,所以在很多情況下,這是你想要的;這也是在switch語句中碰到上述情況的價值。

1

Java規範說:

Every case constant expression associated with a switch statement must be assignable (§5.2) to the type of the switch Expression.

JVM規範,說的類型會提升,但是這是一個不同的(不編譯時間)的問題。

9

switch聲明不限於int。Java語言規範(JLS),section 14.11, The switch Statement,指出

The type of the Expression must be char, byte, short, int, Character, Byte, Short, Integer, or an enum type, or a compile-time error occurs.

byte,因此,不提升到int。在JLS接着說,你在做什麼會導致編譯時錯誤:

Every case constant expression associated with a switch statement must be assignable to the type of the switch Expression.

...因爲128不是分配給一個byte