2016-10-10 6 views
5

Gefunden einige seltsame Dinge in Java.Seltsame Dinge in Java

Code:

System.out.println(System.getProperty("java.version")); 
System.out.println((true) ? (int)2.5 : 3.5); 
System.out.println((true) ? (int)2.5 : 3); 
System.out.println((true) ? (int)2.5 + "" : 3.5); 

Ergebnis:

 
1.8.0_40 
2.0 
2 
2 

Was ist das? Warum gibt der Integer-Wert nur zurück, wenn der Wert für false kein double-Wert ist oder wenn der Wert für true einem Wert hinzugefügt wurde? Warum funktioniert das Runden in der zweiten Zeile mit (int) cast, aber gibt es einen doppelten Wert? Ist es ein Fehler?

+0

Nein, diese Dinge sind keine Fehler. – Jesper

+4

Soweit es den Compiler betrifft, gibt es nur einen Typ für den gesamten '?:' Ausdruck, und das wird dadurch herausgefunden, dass der schmalste gemeinsame Typ zwischen beiden Seiten gefunden wird. –

+0

(Ich gestehe, ich bin überrascht, dass die letzte Zeile kompiliert, obwohl.) –

Antwort

3

In einer schematischen:

(true) ? (int)2.5 : 3.5 

     int  double 
      \  /
      double 

Die double literal 2.5 ist unterabgetasteten bis int 2, dann zurück zu double 2.0 gefördert, weil das die Art des konditionalen Ausdrucks ist.

4

https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25 gibt alle diese Regeln an, die sich exakt mit Ihrer beobachteten Ausgabe verhalten.

Es gibt nur einen Typ für den gesamten ternären Ausdruck, und das wird zurückgegeben und das ist, was System.out.println aufgerufen wird. Wenn Sie in der Tabelle in dieser Spezifikation nachsehen, werden die Typen in den von Ihnen erwähnten Zeilen double, int bzw. Object sein.

2

Der ternäre Operator hat einen konstanten Rückgabetyp.

Vom JLS, section 15.25:

Andernfalls binären numerischen Förderung (§5.6.2) an die Operandentypen angewandt wird, und die Art des konditionalen Ausdrucks ist der geförderte Typ der zweiten und dritter Operanden. Diese

bedeutet, dass in (true) ? (int)2.5 : 3.5, 2.5 zu einem int umgewandelt wird, (abgerundet), dann zu einem verbreiterten double.

In (true) ? (int)2.5 : 3, die int braucht nicht auf eine double erweitert werden, weil die andere Seite auch ein int ist.

schließlich in (true) ? (int)2.5 + "" : 3.5);, es nicht erweitert werden, da es bereits zu einem String umgewandelt worden ist.

Verwandte Themen