2016-01-20 22 views
5

Sono un po 'perplesso per l'output di questo programma:Java JLS specifica la promozione di tipi di wrapper primitivi?

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()); 
    } 
} 

Ecco cosa uscite:

456 isa java.lang.Long 

Sembra che il compilatore è "promuovere" un oggetto di tipo Integer a Long, proprio come normalmente promuoverebbe valori primitivi. Non ho mai sentito parlare della promozione di oggetti e questo comportamento sembra molto sorprendente.

La mia domanda: è questo comportamento veramente corretto secondo il JLS? Se è così mi piacerebbe vedere un riferimento, se possibile.

Oppure si tratta di un bug del compilatore autoboxing-gone-wild?

sto usando:

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) 

risposta

4

Questo è in realtà binario promozione numerico (JLS, Section 5.6.2).

Quando un operatore applica promozione numerico binario ad una coppia di operandi, ciascuno dei quali deve indicare un valore che è convertibile in un tipo numerico, si applicano le regole seguenti, nell'ordine:

  1. Se qualsiasi operando è di un tipo di riferimento, è soggetto alla conversione di unboxing (§5.1.8).

  2. Allargamento conversione primitiva (§5.1.2) viene applicato per convertire uno o entrambi gli operandi come specificato dalle seguenti regole:

    • Se uno degli operandi è di tipo double, l'altro viene convertito a raddoppiare .

    • Altrimenti, se uno degli operandi è di tipo float, l'altro viene convertito in float.

    • In caso contrario, se uno degli operandi è di tipo lungo, l'altro viene convertito in long.

    • In caso contrario, entrambi gli operandi vengono convertiti in tipo int.

promozione numerico binario viene eseguita su operandi di alcuni operatori:

...

  • In alcuni casi, l'operatore condizionale? : (§15.25)

Così, gli operandi sono unboxed e la 456 ottiene allargato a 456L.

Inoltre, il caso specifico di Long e Integer è coperto esplicitamente dalla sezione JLS per l'operatore condizionale, JLS Section 15.25, Table 15.25-C.

BNP (Long, Integer)

dove "BNP" si intende la promozione numerico binario. Di conseguenza, l'espressione dell'operatore condizionale è di tipo long, che viene inserito in un numero da assegnare a Number.

3

Il JLS definisce il tipo dell'espressione a ? b : c in caso b e c sono lunghe e intero rispettivamente, in this table.

Il tipo di espressione è effettivamente Long e esiste effettivamente una promozione numerica binaria (bnp) di Integer to Long.

La regola è precisato here:

Il tipo di un'espressione condizionale numerico viene determinato come segue:

[...]

Altrimenti, promozione numerico binario (§5.6 .2) viene applicato ai tipi di operando e il tipo dell'espressione condizionale è il tipo promosso del secondo e del terzo operando.

Problemi correlati