Nuovo numero intero vs valoreOf

Stavo usando Sonar per rendere il mio codice più pulito, e ha sottolineato che sto usando il new Integer(1) invece di Integer.valueOf(1) . Perché sembra che valueOf non istanzia un nuovo object, quindi è più adatto alla memoria. In che modo valueOf non istanzia un nuovo object? Come funziona? È vero per tutti gli interi?

    Integer.valueOf implementa una cache per i valori da -128 a +127. Vedere l’ultimo paragrafo della Specifica del linguaggio Java, sezione 5.1.7, che spiega i requisiti per il pugilato (solitamente implementato in termini dei metodi .valueOf).

    http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

    Da JavaDoc :

    public static Intero valoreOf (int i) Restituisce un’istanza Integer che rappresenta il valore int specificato. Se non è richiesta una nuova istanza Integer, questo metodo deve essere generalmente utilizzato in preferenza rispetto al costruttore Integer (int), poiché è probabile che questo metodo produca prestazioni significativamente migliori in termini di spazio e tempo memorizzando nella cache i valori richiesti di frequente.

    ValueOf è generalmente utilizzato per l’autoboxing e quindi (se utilizzato per l’autoboxing) memorizza nella cache almeno valori da -128 a 127 per seguire le specifiche di autoboxing.

    Ecco l’implementazione valueOf per Sun JVM 1.5.? Dai un’occhiata all’intera class per vedere come viene inizializzata la cache.

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

    ti stanno spingendo a usare valueOf() invece di new Integer() modo che il metodo valueOf() faccia per te, e memorizza il valore nel caso in cui desideri ottenere lo stesso numero in futuro. In tal caso, il metodo non instatterà il nuovo Integer, ma fornirà quello memorizzato nella cache, ciò che renderà la ‘creazione’ del nuovo Integer molto più veloce e il processo di facile memorizzazione.

    In questo modo potresti causare molti problemi se sei un programmatore java inesperto poiché concluderai che Integer.valueOf(342)==Integer.valueOf(342) , perché potresti (o meno) avere lo stesso puntatore per due interi e probabilmente lo eserciterai in un modo, diciamo, hai imparato in C #, in modo che di tanto in tanto ti mostri bug e non saprai come e da dove vengono questi …

    Dal codice sorgente java.lang.Integer. La cache dei numeri interi è configurabile. Per configurare la dimensione della cache Integer diversa da Sun, è necessario utilizzare la proprietà System java.lang.Integer.IntegerCache.high secondo il codice sorgente.

     /** * Cache to support the object identity semantics of autoboxing for values between * -128 and 127 (inclusive) as required by JLS. * * The cache is initialized on first usage. During VM initialization the * getAndRemoveCacheProperties method may be used to get and remove any system * properites that configure the cache size. At this time, the size of the * cache may be controlled by the vm option -XX:AutoBoxCacheMax=. */ // value of java.lang.Integer.IntegerCache.high property (obtained during VM init) private static String integerCacheHighPropValue; static void getAndRemoveCacheProperties() { if (!sun.misc.VM.isBooted()) { Properties props = System.getProperties(); integerCacheHighPropValue = (String)props.remove("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) System.setProperties(props); // remove from system props } } private static class IntegerCache { static final int high; static final Integer cache[]; static { final int low = -128; // high value may be configured by property int h = 127; if (integerCacheHighPropValue != null) { // Use Long.decode here to avoid invoking methods that // require Integer's autoboxing cache to be initialized int i = Long.decode(integerCacheHighPropValue).intValue(); i = Math.max(i, 127); // Maximum array size is Integer.MAX_VALUE h = Math.min(i, Integer.MAX_VALUE - -low); } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); } private IntegerCache() {} } 

    Da java.lang.Short, java.lang.Byte e java.lang.Long crea una cache da 127 a -128

     private static class LongCache { private LongCache() { } static final Long cache[] = new Long[-(-128) + 127 + 1]; static { for (int i = 0; i < cache.length; i++) cache[i] = new Long(i - 128); } } private static class ShortCache { private ShortCache() { } static final Short cache[] = new Short[-(-128) + 127 + 1]; static { for (int i = 0; i < cache.length; i++) cache[i] = new Short((short) (i - 128)); } } private static class ByteCache { private ByteCache() { } static final Byte cache[] = new Byte[-(-128) + 127 + 1]; static { for (int i = 0; i < cache.length; i++) cache[i] = new Byte((byte) (i - 128)); } }