2010-07-05 196 views
4

有人可以解釋爲什麼這個代碼?java三元運算符

Collection c = (5 == 5) ? new ArrayList() : new HashSet(); 

產生以下編譯器錯誤:

Incompatible conditional operand types ArrayList and HashSet

對於我不明白,下面的解決了這個問題

Collection c = (5 == 5) ? (Collection) new ArrayList() : new HashSet(); 

我使用Java 1.4的原因。

+4

請注意,第一次在Java 1.5及更高版本上編譯。 – BalusC 2010-07-05 17:34:52

+1

在運行Sun的JDK 1.6.0_16版本的機器上工作正常 – MAK 2010-07-05 17:36:13

+0

關閉點,但值得一問 - 看起來像「5 == 5」似乎對除了我之外的其他任何人都不陌生。據我所知,'c'總是會評估爲'new ArrayList()'。任何人都可以解釋爲什麼它可能是有用的做'集合c =(5 == 5)? new ArrayList():new HashSet();'而不是簡單地執行'Collection c = new ArrayList();'考慮到'(5 == 5)'總是計算爲'true'? – 2015-01-03 14:16:46

回答

7

這是一個錯誤在1.4中,並已根據bugreport 5080917修復。

Evaluation This is a bug.

[email protected] 2004-07-30

+0

+1你說得對。我誤讀了規範,現在刪除我的答案。 – Daniel 2010-07-05 17:52:14

+0

這是1.5(老虎)中1.6(野馬)固定的錯誤。它看起來像1.5/3rd Ed JLS中引入的規則的特定實例。 – 2010-07-05 19:59:37

+0

@丹尼爾我想你的答案几乎就在那裏。 – 2010-07-05 20:07:45

3

丹尼爾或多或少地得到這個權利,但刪除了他的答案(五票)。

從第二

相關報價埃德JLS(1.2-1.4)

  • If the second and third operands are of different reference types, then it must be possible to convert one of the types to the other type (call this latter type T) by assignment conversion (§5.2); the type of the conditional expression is T. It is a compile-time error if neither type is assignment compatible with the other type.

其中一種類型必須轉換爲其他的,這是不是ArrayListHashSet真實的,但就是CollectionHashSet和真ArrayListCollection

在第三版JLS(1.5+)

  • Otherwise, the second and third operands are of types S1 and S2 respectively. Let T1 be the type that results from applying boxing conversion to S1, and let T2 be the type that results from applying boxing conversion to S2. The type of the conditional expression is the result of applying capture conversion (§5.1.10) to lub(T1, T2) (§15.12.2.7).

這確實在明顯的事情,事實證明這是比較難以確定和實施(我無意間得到了javac的一個早期版本的崩潰就可以了當其中一個表達式是void)。 IIRC,這是作爲泛型的一部分完成的工作。