77 votes

Nouvel Integer vs valueOf

J'utilisais Sonar pour rendre mon code plus propre, et il a été signalé que j'utilise new Integer(1) au lieu de Integer.valueOf(1) . Comme il semble que valueOf n'instancie pas un nouvel objet, la mémoire est plus conviviale. Comment valueOf ne peut pas instancier un nouvel objet? Comment ça marche? Est-ce vrai pour tous les entiers?

77voto

bkail Points 16610

Integer.valueOf implémente un cache pour les valeurs -128 à +127. Voir le dernier paragraphe de la spécification du langage Java, section 5.1.7, qui explique les conditions requises pour la boxe (généralement implémenté en termes de méthodes .valueOf).

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

30voto

pgras Points 7202

À partir de la JavaDoc:

public static Entier valueOf(int i) Retourne un Entier instance représentant le spécifiée valeur int. Si un nouveau Entier instance n'est pas nécessaire, cette méthode doit généralement être utilisés de préférence pour le constructeur de type Entier(int), que cette méthode est susceptible d'avoir nettement mieux l'espace et le temps de la performance par la mise en cache souvent demandé valeurs.

ValueOf est généralement utilisé pour l'autoboxing et donc (quand il est utilisé pour l'autoboxing) met en cache au moins des valeurs de -128 à 127 pour suivre l'autoboxing la spécification.

Voici l' valueOf de la mise en œuvre de Sun JVM 1.5.? Jetez un oeil à l'ensemble de la classe pour voir comment le cache est initialisé.

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

3voto

ante.sabo Points 763

ils sont vous pousse à utiliser valueOf() au lieu de new Integer() de sorte que la méthode de valueOf() fait pour vous, et des caches de la valeur dans le cas où vous souhaitez obtenir le même nombre de nouveau à l'avenir. Dans ce cas, la méthode ne démarrent des instances new Integer, mais vous donnera le cache, ce qui va faire de "création" de new Integer beaucoup plus rapide et la mémoire conviviale..

De cette façon, vous pouvez vous entraîner vous-même beaucoup de problèmes si vous êtes inexpérimenté programmeur java puisque vous en conclure qu' Integer.valueOf(342)==Integer.valueOf(342), parce que vous pouvez (ou pas) ont le même pointeur de deux Entiers, et sans doute vous allez le pratiquer d'une manière, disons, vous avez appris en C#, donc qui va vous montrer les bugs de temps en temps, et vous ne savez pas comment et où ceux-ci venaient de...

2voto

dungeon Hunter Points 2958

À partir du code source java.lang.Integer. Le cache entier est configurable. Pour configurer la taille du cache Integer autre que Sun, nous devons utiliser la propriété système java.lang.Integer.IntegerCache.high selon le code source.

 /**
 * 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=<size>.
 */

// 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() {}
}
 

À partir de java.lang.Short, java.lang.Byte et java.lang.Long créent un cache de 127 à -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));
}
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X