前几天和我六哥讨论技术的时候说到了 Integer,大家可能觉得 Intger 有什么好说的,不就是 int 吗,Java 装箱拆箱机制。那么现在有这样一个问题:
System.out.println(new Integer(1) == (new Integer(1)));
System.out.println(new Integer(1).equals(new Integer(1)));
System.out.println(Integer.valueOf(1) == Integer.valueOf(1));
System.out.println(Integer.valueOf(129) == Integer.valueOf(129));
这四行代码分别输出什么,为什么? 答案:false、true、true、false
如果你没答出来,那么请继续往下看吧~
对,先说这个类,一看名字就知道是 Integer 缓存,它是 Integer 的一个静态内部类。源码不多,先看代码:
private static class IntegerCache {
static final int low = -128;
static final int high; // 这个值可以在vm属性配置
static final Integer cache[];
static {
... // 给 high 赋值,从 vm 属性配置获取配置值,默认 127
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;
}
}
由上面源码可以看出,IntegerCache 会缓存值为 -128 ~ 127 的 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);
}
所以当调用 Integer.valueOf 的时候,如果值在 -128 到 127 的范围,就会使用 IntegerCache 中的缓存对象。
针对 new Integer(1) == (new Integer(1)),源码没有做特殊处理,就是 new 了两个不同的对象,他们当然是不相等的,返回 false;
针对 new Integer(1).equals(new Integer(1)),可以看一下 Integer.equals() 函数的实现,函数内部是直接比较两个对象的 value 是否相等,他们的 value 都是 1,所以返回 true;
针对 Integer.valueOf(1) == Integer.valueOf(1),就是我们前面提到的 IntegerCache 了,Integer.valueOf 会直接使用缓存好的对象,两个值相等,所以对象也是相同的,返回 true;
针对 Integer.valueOf(129) == Integer.valueOf(129),由于缓存的范围是 -128 ~ 127,值 129 显然是超出范围了,所以会 new 一个新对象,也不会相等,返回 false;
再看一下以下输出:
Integer i = 100;
Integer j = 100;
System.out.print(i == j); //true
以上例子,Java 在编译是会自动装箱,编译为:Integer i = Integer.valueOf(100),又看到了 valueOf,用了缓存的 Integer,所以输出 true。
Integer i = new Integer(100);
int j = 100;
System.out.print(i == j); //true
以上例子,在 int 和 Integer 相比较时,Java 编译器会自动把 Integer 拆箱为 int 类型,所以输出 100。
好,看完了 Integer,我突然想起了其他的包装器类会不会也是这样,于是分别看了一下源码。
我直接说结果吧,有兴趣的同学可以看一下源码:Long,Short 这两个类,内部也缓存了 -128 ~ 127 的对象,Boolean 内部缓存了 TRUE、FALSE 两个对象。和 Integer 类似,都是在调用 valueOf 方法的时候生效,new 的时候不会这样。
作 者:ChanghuiN 原文链接:https://www.hchstudio.cn/article/2019/223d/ 版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。