java: Auto-boxe e casting? [chiuso]


Sono confuso con un piccolo problema, vedere quanto segue:

Double j = new Double(5); // No problem.
double j =5;//

         //But

//Here the problem:

Double j = 5;
Long k =5;      
Float g = 5.0;

Conosco la soluzione ma voglio capire perché in alcune situazioni il cast è fatto implicitamente e in altre no.

Author: user3760992, 2014-06-20

4 answers

Non c'è niente di sbagliato in

Double j = new Double(5);

Perché Java convertirà 5 da un int al double che un costruttore Double prenderà. Convertirà anche il 5 in un double per la riga:

double j =5;

Questa è una conversione primitiva che si allarga.

C'è un problema con queste linee.

Double j = 5;
Long k =5;      
Float g = 5.0;

Java non eseguirà una conversione primitiva di ampliamento (5 a 5.0 o 5L) e una conversione di boxe (double a Double o long a Long) implicitamente. Esso eseguirà uno implicitamente, ma non entrambi. Inoltre, non eseguirà una conversione primitiva di restringimento qui (5.0 a 5.0f).

Il JLS, Sezione 5.2 , afferma:

I contesti di assegnazione consentono l'uso di uno dei seguenti:

  • Una conversione di identità(§5.1.1)

  • Una conversione primitiva in espansione (§5.1.2)

  • A ampliamento conversione di riferimento(§5.1.5)

  • Una boxe conversione (§5.1.7) seguita facoltativamente da una conversione di riferimento allargata

  • Una conversione unboxing (§5.1.8) seguita facoltativamente da una conversione primitiva di ampliamento.

Non consente esplicitamente ciò che le ultime 3 righe stanno tentando di fare: una conversione primitiva di ampliamento seguita da una conversione di boxe.

È interessante notare che Java consente:

Number x = 5;  // boxing followed by widening
double y = new Integer(5);  // unboxing followed by widening
 6
Author: rgettman, 2014-06-20 17:23:32

Il problema con queste tre assegnazioni è che sebbene Java abbia regole sull'ampliamento delle conversioni da primitive a primitive, non ha regole per le conversioni da primitive a wrapper. In altre parole, non esiste una regola che faccia una conversione oltre all'auto-boxing.

Double j = 5;  // 5 is an int literal. It can be auto-boxed only to Integer
Long k =5;     // Same here
Float g = 5.0; // 5.0 is a double literal. It can be auto-boxed only to Double

Puoi correggerli aggiungendo un suffisso corretto o un cast corretto, in questo modo:

Double j = (double)5;
Long k = 5L;      
Float g = (float)5.0;
 3
Author: dasblinkenlight, 2014-06-20 17:17:58

Doppia j = nuova doppia(5); doppio k =j;

Qui si verifica unboxing. ottenere valore dall'oggetto Wrapper e assegnare al tipo di dati primitivo(int, doulbe, float) double k = j; è equivalente a j. doubleValue (); il tipo di ritorno è double

Doppia j = 5;

Vuoi che ti usi in questo modo, devi menzionare il tipo di dati, Doppia a=(doppia)5; o Doppia a = Doppia.Valore di(5);

Questo è autoboxing. Senza sapere che il tipo di dati non può essere cast java, altrimenti dovresti dare corretto tipo di dati primitivo (5.0).

 1
Author: Kannan Thangadurai, 2014-06-26 07:01:41

double d = 5; // ampliamento

Nell'istruzione precedente, l'allargamento sta avvenendo dalla primitiva int a double

Double d = new Double(5); // wrapper classe costruttore utilizzato e passato con int tipo valore 5, ma restituisce wrapper classe Double riferimento d con riferimento al valore 5.0 come jvm farà widening su int tipo valore 5 e ritorno double tipo 5.0 che viene utilizzato dalla classe wrapper Double constructor.

Double d = 5.0; // è auto boxing, è lo stesso come Double d = new Double(5);

Ma, Double d = 5; / / è errato come int il valore del tipo 5 non può essere auto boxed a double valore del tipo e referenziato da Double variabile di riferimento del tipo. jvm non esegue tale ampliamento di tipo primitivo per i valori a cui fare riferimento dalla variabile di riferimento della classe wrapper.

 0
Author: Alok Anand, 2014-06-20 18:00:01