2013-07-29 14 views
9

Warum funktioniert dieser Code?Seltsames Java-Verhalten. Ternärer Operator

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

Und warum wirft dies eine Ausnahme?

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

Aber das Merkwürdigste ist, dass dieser Code auch erfolgreich ohne Ausnahmen läuft:

Float testFloat = null; 
Float f = testFloat; 

Es scheint, dass der ternäre Operator von Java das Verhalten ändert. Kann mir bitte jemand erklären, warum das so ist?

+0

Ich laufe es mit JDK 7u25 und es gab keine Ausnahmen. –

+0

Der dritte Code kann keine Ausnahmen auslösen: Sie deklarieren eine Variable, setzen sie auf null, deklarieren dann eine andere und setzen sie auf den Wert der ersten, die null ist. Keine Ausnahmen konnten geworfen werden –

Antwort

13

Das Verhalten wird in JLS - Conditional Operator angegeben:

Wenn einer der zweiten und dritten Operanden von primitivem Typ T ist, und die Art des andere ist das Ergebnis des Anwendens boxing Umwandlung (§5.1.7) zu T, dann ist der Typ des bedingten Ausdrucks T.

Schwerpunkt meiner. Also, in dem 2 nd Fall:

Float f = true ? testFloat : 0f; 

Seit 3. Zeile wird vom Urtyp (T), die Art des Ausdrucks würde float Typ sein - T. So UnboxingtestFloat die derzeit ein null Bezug auf float führt in NPE.


Was die 1 st Fall relevante Teil ist die letzte:

Ansonsten sind die zweiten und dritten Operanden sind von Typen S1 und S2 jeweils. Sei T1 der Typ, der sich aus der Anwendung der Box-Konvertierung auf S1 ergibt, und sei T2 der Typ, der sich aus der Anwendung der Box-Konvertierung auf S2 ergibt. Der Typ des bedingten Ausdrucks ist das Ergebnis der Anwendung der Capture-Konvertierung (§5.1.10) auf lub (T1, T2) (§15.12.2.7).

So nach, dazu:

null type - S1 
float  - S2 

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

und geben Sie dann ein bedingter Ausdruck wird - Float. Es wird kein Unboxing von null benötigt, und daher auch kein NPE.

+0

Oh ... Ich habe es jetzt! Vielen Dank für die Antwort! – user2452103

+0

Ich konnte die genaue Regel nicht finden, warum 'wahr? null: 0f' ist aber ok. Können Sie diesen Teil in der JLS genau lokalisieren? Oder wäre das einfach "Wenn der zweite und der dritte Operand den gleichen Typ haben (was der Null-Typ sein kann), dann ist das der Typ des bedingten Ausdrucks.", Wobei "0f" in "Float" eingerahmt wird? –

+0

@Huster. Lass mich auschecken. –

Verwandte Themen