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.
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
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;
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).
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.