所学知识
这里涉及到的知识点为Java的自动装箱、拆箱问题
先看简单示例:
第一组输出为true,第二组false,第三组false。第二组false很正常因为Integer对象地址不同,但为什么第一组与第三组结果不同,不是应该一样的吗?
Integer a = 127;
Integer b = 127;
System.out.println(a == b);
Integer c = new Integer(128);
Integer d = new Integer(128);
System.out.println(c == d);
Integer e = 128;
Integer f = 128;
System.out.println(e == f);
知识探索:
要弄明白这个问题,首先要熟练掌握Java自动装箱、拆箱相关的知识,Java中的自动装/拆箱发生在运算操作和比较操作时,例如:
Integer a = 10;
a = a + 2;
System.out.println(a > 10);
a = a + 2; 先把a拆箱为int类型,再进行a + 2运算,再把结果装箱为Integer类型。
当使用==来比较时有三种情况:
Integer a = 10;
Integer b = 10;
Integer c = new Integer(12);
Integer d = new Integer(12);
System.out.println(a == 10);
System.out.println(a == b);
System.out.println(c == d);
1、 a == 10 左右两边一边int类型一边Integer类型,a先拆箱再比较。
2、 a == b 与 c == d都是对地址进行比较,不同的是a、b都指向同一对象,Integer a,b=10;中的10存放在常量区,a,b 都指向它。c, d中的new Integer()在堆中产生两个不同对象,地址不同因此返回false。
为什么(Integer)127 == (Integer)127 和 (Integer)128 == (Integer)128的值不同:
Integer类部分源码如下:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer[] cache;
private IntegerCache() {
}
static {
int var0 = 127;
String var1 = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
int var2;
if (var1 != null) {
try {
var2 = Integer.parseInt(var1);
var2 = Math.max(var2, 127);
var0 = Math.min(var2, 2147483518);
} catch (NumberFormatException var4) {
}
}
high = var0;
cache = new Integer[high - -128 + 1];
var2 = -128;
for(int var3 = 0; var3 < cache.length; ++var3) {
cache[var3] = new Integer(var2++);
}
assert high >= 127;
}
}
大概意思就是:Integer类 -128~127 之间的值都是直接从缓存中取出的,(Integer)127 == (Integer)127两边装箱后,实际指向堆内存中同一个对象,大于127 后就new一个新的对象返回。(Integer)128 == (Integer)128,装箱为引用类型后,没有做缓存,指向堆内存中不同对象,所以比较结果为false。至于为什么要缓存,若不缓存,每次都要new一个新对象,资源消耗多,所以缓存一些常用的数,来减少资源损耗。