2016-07-04 16 views
14

Qual è la differenza tra i seguenti:Qual è la differenza tra (intero) y e nuovo numero intero (y) in java?

Integer in = (Integer)y;

e

Integer in = new Integer(y);

voglio convertire int tipo di Integer tipo e viceversa. Ecco il mio codice per farlo:

public class CompareToDemo { 

    public static void main(String[] args) { 
    // Integer x=5; 
    int y=25; 

    System.out.println(y+" this is int variable"); 

    Integer in = (Integer)y; 

    //Integer in = new Integer(y); 

    if(in instanceof Integer){ 
     System.out.println(in +" this is Integer variable"); 
    } 
    } 
} 
+6

Per questa conversione è necessario utilizzare 'Integer.valueOf()'. Da javadoc "Se non è richiesta una nuova istanza Integer, questo metodo dovrebbe generalmente essere utilizzato preferibilmente nel costruttore Integer (int), in quanto è probabile che questo metodo produca prestazioni significativamente migliori in termini di spazio e tempo memorizzando nella cache il valore richiesto frequentemente" – Jens

risposta

9

Se tutto quello che vogliamo fare è quello di convertire un int primitivo a un oggetto Integer, si hanno quattro opzioni

Integer in = (Integer)y;   // 1 explicit cast 
    Integer in = y;     // 2 implicit cast (autoboxing) 
    Integer in = new Integer(y);  // 3 explicit constructor 
    Integer in = Integer.valueOf(y); // 4 static factory method 

Il modo più preferibile qui è 2 (autoboxing). Il costruttore esplicito (3) è il meno preferibile, in quanto potrebbe avere qualche piccolo impatto sulle prestazioni.

Inoltre, non sono strettamente equivalenti. Si consideri:

public static void main(String[] args) { 
    int x = 25; 
    Integer a = new Integer(x); 
    Integer b = new Integer(x); 
    System.out.println(a == b);  // false 
    Integer c = Integer.valueOf(x); 
    Integer d = Integer.valueOf(x); 
    System.out.println(c == d);  // true 
    Integer e = (Integer)x; 
    Integer f = (Integer)x; 
    System.out.println(e == f);  // true 
} 

Questo perché interi piccoli vengono memorizzati nella cache (details here).

9

Per dirla in breve,

  • La linea Integer in = (Integer)y; utilizza un cast inutile.
  • La riga Integer in = new Integer(y); crea un'istanza Integer.

Ogni caso in dettaglio

In primo luogo, prendiamo in considerazione il caso di cast esplicito.

Integer i = (Integer)10; 

Il compilatore capisce che 10 è un tipo primitivo int e il fatto che deve essere avvolto dal suo Integer per renderlo compila. Sembra javac farà la seguente:

Integer i = (Integer)Integer.valueOf(10); 

Ma il compilatore è abbastanza intelligente da fare fusione inutili, (Integer) appena verrà omessa:

Integer i = Integer.valueOf(10); 

Avanti, c'è il caso con la creazione dell'istanza.

Integer i = new Integer(10); 

Qui è tutto semplicemente. Una nuova istanza della classe Integer verrà comunque creata. Ma, come dice la documentazione, di solito, non è il modo appropriato:

Raramente è opportuno utilizzare questi costruttori. Gli stabilimenti statici valueOf() sono in genere una scelta migliore, poiché è probabile che producano prestazioni significativamente migliori in termini di spazio e tempo.

Conclusione

Nella scrittura di codice di tutti i giorni, usiamo di solito autoboxing and unboxing. Sono conversioni automatiche tra i tipi primitivi e le corrispondenti classi wrapper degli oggetti (è stato introdotto in Java 5). Quindi non è necessario pensare molto ai metodi Xxx.valueOf(xxx) e .xxxValue(). È così conveniente, no?

Integer i = 10; // autoboxing 
int j = i; // unboxing 
+2

" Non hai bisogno di pensare. " - Solo punto di obiezione. Non sostengo che la VM gestisca il lavoro "sporco" per te - ** ma ** devi ancora essere consapevole di cosa sta succedendo. Proprio l'altro giorno c'era una domanda in cui un ragazzo incasinato la sincronizzazione dei thread a causa del meccanismo di pool Integer. – Fildor

+2

@Fildor: l'utilizzo delle istanze 'Integer' come chiave di sincronizzazione è comunque un disegno non valido, indipendentemente dal fatto che il raggruppamento avvenga o meno. – Holger

+2

@Holger Sono d'accordo. Ma non era questo il mio punto. Volevo solo dire "Non devi pensare" è ** semplicemente non vero **. _ Ovviamente_ devi sapere che c'è un po 'di boxe/Unboxing in corso dietro le quinte. Altrimenti, prima o poi ti metterai nei guai. L'esempio con quel problema di sincronizzazione era solo uno dei tanti pensabili. – Fildor

4

Per ogni primitive type in Java, v'è una corrispondente classe involucro. È possibile convertire tra questi tipi primitivi e le corrispondenti classi wrapper.Questo è chiamato boxing e unboxing. Quando si scrive

Integer in = (Integer)y; //this is unnecessary casting 

o

Integer in = new Integer(y); //create a new instance of Integer class 

si sta convertendo principalmente tra il tipo primitivo e classe wrapper. Ma Java ha una funzionalità chiamata Auto Boxing and Unboxing Dove java farà questo casting per te. Basta scrivere

int iPrimi = 20; 
Integer iWrapper = iPrimi; //Autoboxing 
int iPrimi2 = iWrapper; //Auto unboxing 

Autoboxing e Unboxing riducono le prestazioni. Primitives seems to be 2-3 times faster then it’s Integer equivalent. Quindi non usarli se non ne hai bisogno.

+0

Hai un errore di battitura nel tuo secondo codice di Esempio. Interger -> Numero intero – Vincent

+3

Ermahgerd! Interger! – CodeNewbie

+1

Per ultimo esempio, intendi iPrimi2 = iWrapper? –

Problemi correlati