This is the 15th day of my participation in the August Text Challenge.More challenges in August

The interview questions

First, a common interview question: What does this code output when run?

When the above code is run, it will eventually print false and true; Why is that?

If i3 and i4 are two different objects, it should also return false. Let’s go down slowly

Integer cache mechanism

Let’s take a look at his source code.

When Integer I =128; ValueOf (int I) =new Integer(128); valueOf(int I);

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    / / packing
    return new Integer(i);
}
Copy the code

As you can see from the source code above, before boxing, an if statement is executed. This if statement determines whether the incoming value is in the cache. If it is in the cache, it returns the value directly.

//Integer wrapper class cache source code
private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if(integerCacheHighPropValue ! =null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }
        private IntegerCache(a) {}}Copy the code

Integer cache ranges from -128 to 127, so the process is as follows:

If i3==i4 is in the cache pool, it will be true. If i3==i4 is in the cache pool, it will be true. For objects that are not in the cache, a new space will be opened in the heap to store objects, so the == comparison will return different addresses.

Other wrapper class caching mechanisms

In addition to Integer, other wrapper classes also use caching techniques;

Long

Cache range: -128 to 127

public static Long valueOf(long l) {
    final int offset = 128;
    if (l >= -128 && l <= 127) { // will cache
        return LongCache.cache[(int)l + offset];
    }
    return new Long(l);
}


private static class LongCache {
    private LongCache(a){}

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

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

Byte

Cache range -128 127 (byte range: a byte is 8 bits, so the value range is **-2^7 2^7-1**)

public static Byte valueOf(byte b) {
    final int offset = 128;
    return ByteCache.cache[(int)b + offset];
}

private static class ByteCache {
    private ByteCache(a){}

    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)); }}Copy the code

Character

Cache range 0 to 127 (ASCII code range)

public static Character valueOf(char c) {
    if (c <= 127) { // must cache
        return CharacterCache.cache[(int)c];
    }
    return new Character(c);
}

private static class CharacterCache {
    private CharacterCache(a){}

    static final Character cache[] = new Character[127 + 1];

    static {
        for (int i = 0; i < cache.length; i++)
            cache[i] = new Character((char)i); }}Copy the code

Short

Cache range: -128 to 127

public static Short valueOf(short s) {
    final int offset = 128;
    int sAsInt = s;
    if (sAsInt >= -128 && sAsInt <= 127) { // must cache
        return ShortCache.cache[sAsInt + offset];
    }
    return new Short(s);
}

private static class ShortCache {
    private ShortCache(a){}

    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)); }}Copy the code

Boolean

Cache range true false It sets only two static variables to act as caches

public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);

public static Boolean valueOf(boolean b) {
    return (b ? TRUE : FALSE);
}
Copy the code

advice

It is recommended to override equals() when wrapping classes to compare whether data is the same.