Integer 类型在范围[-128,127] 使用==的比较问题
直接上代码:
public static void main(String[] args) {
Integer a = new Integer(1);
Integer b = new Integer(1);
System.out.println(a==b);
System.out.println(a.equals(b));
a=1;
b=1;
System.out.println(a==b);
a=127;
b=127;
System.out.println(a==b);
a=128;
b=128;
System.out.println(a==b);
}
运行结果:
疑问:为什么127比较时为true,128为false???
结果分析:
- 对于基本类型,= = 判断两个值是否相等,基本类型没有 equals() 方法。
- 对于引用类型,= = 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价。
第一个结果是false,显而易见是new了两个对象。
第二个结果是true,因为equals比较的是两个对象的真实值,也就是堆中的1。
第三个结果是true,直接给ab赋值。
第四个结果是true,直接给ab赋值。
第五个结果是false,直接给ab赋值。
这时候问题来了,为什么同样是赋值,结果却不一样?
a=127;自动装箱,相当于调用了Integer.valueOf(127);方法。
自动装箱时首先判断i值是否在-128和127之间,如果在-128和127之间则直接从IntegerCache.cache缓存中获取指定数字的包装类;不存在则new出一个新的包装类。
IntegerCache内部实现了一个Integer的静态常量数组,在类加载的时候,执行static静态块进行初始化-128到127之间的Integer对象,存放到cache数组中。cache属于常量,存放在java的方法区中。这样调用时会使用缓存池中的对象,多次调用会取得同一个对象的引用。
我们查看一下Integer类的源码中有这样一个方法:
public static Integer valueOf(int paramInt) {
assert (IntegerCache.high >= 127);
if ((paramInt >= -128) && (paramInt <= IntegerCache.high))
return IntegerCache.cache[(paramInt + 128)];
return new Integer(paramInt);
}
关于装箱插箱和缓存池的更多知识:https://blog.youkuaiyun.com/Brad_PiTt7/article/details/98774996