2013-07-29 14 views
9

このコードはなぜ機能しますか?奇妙なJavaの動作。 3進演算子

Float testFloat = null; 
Float f = true ? null : 0f; 

なぜこの例外が発生しますか?

Float testFloat = null; 
Float f = true ? testFloat : 0f; 

しかし、奇妙なことは、このコードはまた、例外なしで正常に動作することです:

Float testFloat = null; 
Float f = testFloat; 

Javaの三項演算子は、動作を変更しているようです。誰でもこれがなぜなのか説明できますか?

+0

JDK 7u25で実行しても、例外は発生しませんでした。 –

+0

3つ目のコードでは、例外をスローすることはできません:1つの変数を宣言し、それをヌルに設定してから別の変数を宣言し、最初の値をnullに設定しています。例外は投げられないかもしれない –

答えて

13

挙動をJLS - Conditional Operatorで指定されている:

第二及び第三のオペランドの一方はプリミティブ型Tであり、および他のタイプはボクシング変換(§5.1.7)を適用した結果である場合Tには、、条件式の種類はTとなります。

強調鉱山。だから、2 ND場合: - T第3オペランドがプリミティブ型(T)であるので

Float f = true ? testFloat : 0f; 

、式の型はfloat型であろう。だから、float、現在null参照ですアンボクシングtestFloatは、NPEになります。 1 ST場合、関連部分が最後のものであるとして


そうでない場合、第二及び第三のオペランドは、それぞれのタイプのS1とS2です。 Q1をボクシング変換をS1に適用した結果のタイプをT1とし、S2にボクシング変換を適用した結果のタイプをT2とする。条件式のタイプは、キャプチャ変換(§5.1.10)をlub(T1、T2)(§15.12.2.7)に適用した結果です。

null type - S1 
float  - S2 

null type - T1 (boxing null type gives null type) 
Float  - T2 (float boxed to Float) 

をして、条件式のタイプはなり - Floatは:

ので、これに応じました。 nullのアンボクシングは不要であり、したがってNPEはありません。

+0

ああ...私はそれを今得た! Thx uは答えのためにそんなに! – user2452103

+0

なぜ真実なルールが見つからなかったのですか? null:0f'でもOKです。あなたはJLSのその部分を突き止めることができますか?つまり、2番目と3番目のオペランドが同じ型(null型かもしれません)であれば、それは条件式の型です。 "、ここで' 0f'は 'Float'に囲まれていますか? –

+0

@Huster。私にチェックアウトさせてください。 –