2016-01-20 17 views
5

Ich bin etwas verwirrt durch die Ausgabe dieses Programms:Gibt die Java JLS die Heraufstufung primitiver Wrapper-Typen an?

public class xx { 
    public static void main(String[] args) throws Exception { 
     Number x = false ? new Long(123) : new Integer(456); 
     System.out.println(x + " isa " + x.getClass().getName()); 
    } 
} 

Hier ist, was es gibt:

456 isa java.lang.Long 

Es scheint, der Compiler ein Objekt vom Typ Integer zu Long ist „Förderung“, wie es würde normalerweise primitive Werte fördern. Ich habe noch nie von Objekt Promotion gehört und dieses Verhalten scheint sehr überraschend.

Meine Frage: Ist das wirklich richtiges Verhalten nach der JLS? Wenn ja, würde ich gerne eine Referenz sehen, wenn möglich.

Oder ist das eine Art von Autoboxing-Wild-Compiler Bug?

Ich verwende:

java version "1.8.0_60" 
Java(TM) SE Runtime Environment (build 1.8.0_60-b27) 
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode) 

Antwort

4

Dies ist eigentlich binäre Zahlen Förderung (JLS, Section 5.6.2).

Wenn ein Operator mit einem Paar von Operanden binäre Zahlen Aktion gilt, von denen jeder einen Wert bezeichnen müssen, die in einen numerischen Typ konvertierbar ist, gelten die folgenden Regeln, um:

  1. Wenn Jeder Operand ist von einem Referenztyp und unterliegt der Unboxing-Konvertierung (§ 5.1.8).

  2. Widening primitive Umwandlung (§5.1.2) wird entweder oder beiden Operanden zu konvertieren, wie durch die folgenden Regeln festgelegt:

    • Falls einer der Operanden vom Typ double ist, wird der andere zu verdoppeln umgewandelt .

    • Andernfalls, wenn einer der Operanden vom Typ float ist, wird der andere in float konvertiert.

    • Andernfalls, wenn einer der Operanden vom Typ long ist, wird der andere in long konvertiert.

    • Andernfalls werden beide Operanden in den Typ int konvertiert.

Binary numerische Förderung wird auf die Operanden bestimmter Operatoren durchgeführt:

...

  • In bestimmten Fällen kann der Bedingungsoperator? : (§15.25)

die Operanden sind also unboxed und die 456-456L erweitert wird.

Auch der spezielle Fall von Long und Integer wird explizit durch den JLS-Abschnitt für den bedingten Operator JLS Section 15.25, Table 15.25-C abgedeckt.

compete (Long, Integer)

wo "compete" binäre Zahlen Förderung bedeutet. Daher ist der Bedingungsoperatorausdruck vom Typ long, der in eine eingereiht wird, um einer Number zugewiesen zu werden.

3

Die JLS definiert den Typ des Ausdrucks a ? b : c bei b und c sind lang und Integer bzw. in this table.

Der Typ des Ausdrucks ist tatsächlich Long, und es gibt tatsächlich eine binäre numerische Heraufstufung (Bnp) von Integer zu Long.

Die Regel ist, weitere detaillierte here:

Der Typ eines numerischen Bedingungsausdruck wird wie folgt bestimmt:

[...]

Ansonsten binäre Zahlen Förderung (§5.6 .2) wird auf die Operandentypen angewendet, und der Typ des bedingten Ausdrucks ist der beschleunigte Typ des zweiten und dritten Operanden.