2010-10-28 76 views
8

可能重複:
Booleans, conditional operators and autoboxing
Java, Google Collections Library; problem with AbstractIterator?Java的自動裝箱/拆箱wierdness

下面的代碼產生NPE:

Integer test = null; 
Integer test2 = true ? test : 0; 
System.out.println(test2); 

要正確打印出「空「沒有例外要求這個代碼:

Integer test = null; 
Integer test2 = true ? test : (Integer)0; 
System.out.println(test2); 

很明顯在第一個實例爲「測試」被拆箱(轉換爲本地INT),但是爲什麼呢?爲什麼在三元運算符中更改其他表達式(如第二個示例中所述)?任何人都可以提供某種形式的敘述,包括何時,什麼以及爲什麼這兩個例子中的東西都被裝箱和拆箱?

+0

請參閱http://www.mail-archive.com/[email protected]/msg32723.html – Adam 2010-10-28 17:52:49

+0

或者[Java,Google Collections Library; AbstractIterator的問題? ](http://stackoverflow.com/questions/1821510/java-google-collections-library-problem-with-abstractiterator),具體關於'int'。 – 2010-10-28 17:53:59

+0

對於這個特定的例子,仍然沒有人回答何時裝箱和自動裝箱的順序。 – GreenieMeanie 2010-10-28 18:06:28

回答

18

section 15.25 of the Java Language Specification

類型的條件表達式的確定如下:

  • 如果第二和第三個操作數具有相同的類型(其可以是空型),然後那就是條件表達式的類型。
    • 如果第二個和第三個操作數中的一個的類型爲布爾型,而另一個的類型爲布爾型,則條件表達式的類型爲布爾型。
    • 如果第二個和第三個操作數中的一個是空類型,而另一個的類型是引用類型,那麼條件表達式的類型就是該引用類型。
    • 否則,如果所述第二和第三操作數具有可轉換類型(§5.1.8),以數字類型,則有幾種情況:
      • 如果操作數中的一個是式字節或字節和的其他類型爲short或Short,則條件表達式的類型很短。
      • 如果其中一個操作數的類型是T,其中T是byte,short或char,另一個操作數是類型爲int的常量表達式,其值可表示爲T類型,則條件表達式的類型爲T
      • 如果其中一個操作數的類型是Byte,另一個操作數是int類型的常量表達式,其值可以用byte類型表示,那麼條件表達式的類型就是byte。
      • 如果其中一個操作數的類型爲Short,另一個操作數的類型爲int的常量表達式的值可以用short類型表示,則條件表達式的類型很短。
      • 如果其中一個操作數是類型的,字符和另一個操作數是int類型的常量表達式,其值可以在char類型中表示,則條件表達式的類型爲char。
      • 否則,對操作數類型應用二進制數字提升(第5.6.2節),並且條件表達式的類型是第二個和第三個操作數的提升類型。請注意,二進制數字提升會執行拆箱轉換(§5.1.8)和值集轉換(§5.1.13)。

因此它下面的最後一顆子彈,執行二進制數值提升,其執行拆箱轉換。因此,即使您將其分配給Integer,條件運算符表達式的類型也是int。它試圖在null上執行拆箱轉換,因此是例外。