2012-01-27 13 views
21

recenlty ho visto il codice (Java) come questo:differenze tra new Integer (123), Integer.valueOf (123) e solo 123

myMethod(new Integer(123)); 

Attualmente sto refactoring del codice, e non v'è una punta in strumento Sonar, che è più memoria amichevole per usare sth come questo:

myMethod(Integer.valueOf(123)); 

Tuttavia, in questo caso, credo che non v'è alcuna differenza se avrei usato:

myMethod(123); 

Potrei capire che, se passassi una variabile al metodo, ma int hard coded? O se ci sarebbe Long/Double etc e voglio Long rappresentazione del numero. Ma numero intero?

+4

in realtà non importa se si esegue 'myMethod (Integer.valueOf (123))' o 'myMethod (123)' come autoboxing userà 'Integer.valueOf()' per te. giudicate voi stessi quale è più leggibile. (supponendo che 'myMethod' prenda' Intero') – soulcheck

risposta

27

new Integer(123) creerà una nuova istanza Object per ciascuna chiamata.

Secondo il javadoc, Integer.valueOf(123) ha la differenza che memorizza nella cache oggetti ... così si può (o non può) finire con lo stesso Object se lo si chiama più di una volta.

Per esempio, il seguente codice:

public static void main(String[] args) { 

     Integer a = new Integer(1); 
     Integer b = new Integer(1); 

     System.out.println("a==b? " + (a==b)); 

     Integer c = Integer.valueOf(1); 
     Integer d = Integer.valueOf(1); 

     System.out.println("c==d? " + (c==d)); 

    } 

ha la seguente uscita:

a==b? false 
c==d? true 

Per quanto riguarda utilizzando il valore int, si utilizza il tipo primitivo (considerando il metodo utilizza anche la tipo primitivo sulla sua firma) - userà un po 'meno di memoria e potrebbe essere più veloce, ma non sarà possibile aggiungerlo alle raccolte, per esempio.

Osservare anche Java AutoBoxing se la firma del proprio metodo utilizza Integer - quando lo si utilizza, la JVM chiamerà automaticamente Integer.valueOf() per voi (quindi utilizzando anche la cache).

+1

Quindi la funzione di autoboxing crea sempre un nuovo oggetto? O può anche fare uso del caching? Se aggiungi queste informazioni al tuo post, penso che la tua sarà la migliore risposta. –

+0

@Marcelo ... puoi per favore anche quell'informazione che Alex D aveva suggerito ... –

+1

@MananShah è già lì (: Sì - autoboxing usa 'Integer.valueOf()', quindi usa la cache. – Marcelo

5

public static Integer valueOf(int i)

restituisce un'istanza numero intero che rappresenta il valore int specificato. Se non è richiesta una nuova istanza Integer, questo metodo deve essere utilizzato in genere come prefisso Integer (int), come è probabile che questo metodo produca prestazioni e tempo significativamente migliori memorizzando nella cache i valori richiesti di frequente.

Parametri:
i - un valore int.
Resi:
a Istanza intera che rappresenta i.
dal:
1,5

riferiscono http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Integer.html#valueOf%28int%29

Questa variante di valueOf è stata aggiunta nel JDK 5 per Byte, Corto, Integer, e Long (esisteva già nel caso banale booleano dal JDK 1.4). Tutti questi sono, ovviamente, oggetti immutabili in Java.Usato per essere quello che se avessi bisogno di un oggetto intero da un int, dovresti costruire un nuovo intero. Ma in JDK 5+, dovresti davvero usare valueOf perché Integer ora memorizza nella cache oggetti interi tra -128 e 127 e può restituirti lo stesso oggetto intero (0) ogni volta invece di sprecare una costruzione di oggetti su un intero identico completamente nuovo oggetto.

private static class IntegerCache { 
private IntegerCache(){} 

static final Integer cache[] = new Integer[-(-128) + 127 + 1]; 

static { 
    for(int i = 0; i < cache.length; i++) 
    cache[i] = new Integer(i - 128); 
} 
} 

public static Integer valueOf(int i) { 
final int offset = 128; 
if (i >= -128 && i <= 127) { // must cache 
    return IntegerCache.cache[i + offset]; 
} 
    return new Integer(i); 
} 

riferiscono Why YOU should use Integer.valueOf(int)

EDIT

autoboxing e creazione dell'oggetto:

Il punto importante considerare è che autoboxing non riduce creazione dell'oggetto, ma riduce codice complessità. Una buona regola empirica consiste nell'utilizzare tipi primitivi dove non c'è bisogno di oggetti, per due ragioni:

I tipi primitivi non saranno più lenti dei loro corrispondenti tipi di wrapper e potrebbero essere molto più veloci. Ci può essere un comportamento inaspettato che coinvolge == (confronta i riferimenti) e .equals() (confronta i valori).

Normalmente, quando i tipi primitivi sono racchiusi nei tipi di wrapper, la JVM alloca la memoria e crea un nuovo oggetto. Ma per alcuni casi speciali, la JVM riutilizza lo stesso oggetto.

Quello che segue è l'elenco dei primitivi memorizzato come oggetti immutabili:

  • valori booleani true e false

  • Tutti byte Valori

  • valori brevi tra -128 e 127

  • valori int tra -128 e 127

  • char nell'intervallo \ u0000 a \ u007F

riferiscono http://today.java.net/pub/a/today/2005/03/24/autoboxing.html#performance_issue

1

int è tipo primitivo, non un oggetto.

new Integer(123) e Integer.valueOf(123) entrambi restituiscono Integer oggetto che rappresenta il valore 123. Come per javadoc per Integer.valueOf():

restituisce un'istanza numero intero che rappresenta il valore int specificato. Se non è richiesta una nuova istanza Integer, questo metodo dovrebbe generalmente essere utilizzato da rispetto al costruttore Integer (int), poiché questo metodo è che offre prestazioni significativamente migliori in termini di spazio e tempo memorizzando nella cache i valori richiesti di .

1

Il tuo metodo richiede un int o un Integer?

new Integer(int) e Integer.valueOf(int) entrambi restituiscono Integer oggetti, ma valueOf dovrebbe essere preferito in quanto è più efficace perché restituisce oggetti memorizzati nella cache. Se il tuo metodo richiede uno Integer, devi usare Integer.valueOf.

Se il metodo richiede uno int, è necessario utilizzare uno int (ad esempio 123).

Tuttavia, non è strettamente necessario abbinare tipi in questo modo per autoboxing, che converte automaticamente un int ad una viceversa Integer e quando i tipi non corrispondono. Ciò consente di passare un int in un metodo che richiede un Integer e un Integer in un metodo che richiede un int. Ma tieni presente che ci sono dei costi di performance associati all'autoboxing. L'esempio più comune di quando si utilizza l'autoboxing è se si desidera memorizzare le primitive in una raccolta.

1

intervallo compreso tra -128 e +127 implementazioni nella cache.

Integer a = new Integer(1); 
Integer b = new Integer(1); 

System.out.println("a==b? " + (a==b)); 

Integer c = Integer.valueOf(127); 
Integer d = Integer.valueOf(127); 

System.out.println("c==d? " + (c==d)); 

Integer e = Integer.valueOf(128); 
Integer f = Integer.valueOf(128); 

System.out.println("e==f? " + (e==f)); 

consultare questa specifica Java:

http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7

in JDK 5+, si dovrebbe davvero utilizzare valueOf perché Integer ora memorizza nella cache oggetti interi fra -128 e 127 e possono mano indietro la stessa identica Integer (0) oggetto ogni volta invece di sprecare una costruzione di oggetto su un oggetto intero identico completamente nuovo.