Integer.valueOf(int) and the inside story of autoboxing

Why does Integer provide a valueOf(xx) method with the same function as new Integer(xx). After reading the source code, I found an amazing inside story.

public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
 return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i); // if there is no cache, new
    }

It turns out that a static inner class IntegerCache is defined in the Integer class.

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

After the class is loaded, several Integer objects will be cached in the memory, the default is from -128 to 127, and high can be configured (XX:AutoBoxCacheMax=200). Call valueOf(x), when x>=-128 and x<=high, directly fetch the object in the cache (heap), without new, if it is not in this range, new. We know that autoboxing (int->Integer) will occur when Integer a = 12, which actually calls Integer.valueOf(12), which is verified by javap as follows:

localhost:tmp javahongxi$ javap -c T
Warning: binary file T contains tmp.T
Compiled from "T.java"
public class tmp.T {
  java.lang.Integer i;

  public tmp.T;
    Code:
       0: aload_0       
       1: invokespecial #1 // Method java/lang/Object."<init>":V
       4: aload_0       
       5: bipush 12
       7: invokestatic  #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      10: putfield      #3 // Field i:Ljava/lang/Integer;
      13: return        
}

At this point, we can draw an important conclusion: For integers in the range of -128~127, we must never declare them with new Integer, please use automatic boxing or Integer.valueOf.

Finally we look at the equals method,

private final int value;

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
 return value == ((Integer)obj).intValue;
        }
        return false;
    }

Now, we should be able to deal with all kinds of written test questions about Integer== judgment.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324527772&siteId=291194637