Integer为什么要提供功能与new Integer(xx)一样的valueOf(xx)方法呢,看了源代码之后,我发现了惊人的内幕。
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); // 缓存里没有则new }
原来,Integer类里定义了一个静态内部类IntegerCache,
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 {} }
改类加载后会在内存里缓存若个个Integer对象,默认从-128~127,high可配(XX:AutoBoxCacheMax=200)。调用valueOf(x),当x>=-128且x<=high时直接取缓存(堆)里的对象,不用new,不在这个范围的则new。我们知道Integer a = 12会发生自动装箱(int->Integer),实际上是调用了Integer.valueOf(12),用javap验证如下:
localhost:tmp javahongxi$ javap -c T 警告: 二进制文件T包含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 }
到此,我们可以得出一个重要的结论:-128~127范围内的整数,我们千万不要用new Integer来声明,请用自动装箱或Integer.valueOf。
最后我们看看equals方法,
private final int value; public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue; } return false; }
现在,我们应该能应对各种关于Integer==判断的笔试题了。