在牛客网上看到这样一道题目,判断一下打印的结果java
public static void main(String[] args){ Integer i1 = 128; Integer i2 = 128; System.out.println(i1==i2); Integer i3 = 100; Integer i4 = 100; System.out.println(i3==i4); }
刚开始看到是,是这样来判断的:由于 Integer i1 = 128 这条语句,Integer 会启用自动装箱功能,调用 Integer.valueOf 方法返回一个 Integer 对象,所以这四个对象应该指向不一样的地址,因此打印的结果是两个 false。可是在 eclipse 运行结果以下,为何会这样呢?编程
首先想到的就是 Integer.valueOf 这个方法有点蹊跷,所以就去看了一下它的源码,它的内部实现以下:数组
public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
从中能够看出,valueOf 方法首先会判断 i 值是否在一个范围内,若是是的话,会从 IntegerCache 的 cache(实际上是一个用 final static 修饰的数组) 中返回 Integer 对象,若是不在这个范围内,会建立一个新的 Integer 对象。那么就看一下这个范围是什么吧。跟到 IntegerCache 类内部,能够看到它定义的两个变量,low 为 -128,high 还未定义。eclipse
static final int low = -128; static final int high;
经过 ctrl+F 查找 high 是何时建立的,发现是在一个静态代码块里面:code
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; }
从中能够看出,high 的值是由 h 决定的,h 通常为 127。这说明,当 valueOf 传入的参数值在 -128~127 之间,这些数值都会存储在静态数组 cache 中。所以,在 valueOf 方法里,参数在 -128~127 之间,返回 Integer 对象的地址引用是同样的,对于题目也有了正确的解答。orm
刚开始学编程时,若是碰到问题时,都是把报错的信息赋值到百度或者谷歌上进行搜索,直接根据被人的踩坑经验,按照他们给的步骤来解决问题,如今我又发现了一种更高效的解决方案 -- 直接看源码,直接了解底层的实现,很快就能够解决问题了。因此,把本身的基础打牢,勿以浮沙筑高台!对象