Integer对象的一些误解

看代码:

1
2
3
4
5
6
7
8
9
public void testInteger()
{
Integer a = 1;
Integer b = 1;
Integer c = 128;
Integer d = 128;
System.out.println(a == b);
System.out.println(c == d);
}

结果是什么?

 

 

 

 

答案是

1
2
3
true
false

这里先明确一个概念,对象之间的直等(==)比较的是两个内存的地址。而boolean byte char short int long float double八大基础类型比较的是值,即true==false,3==6这样比较的。

那么,int的包装类型Integer对象为什么有的相等,有的不相等?

且看Integer.java源码是怎么写的

1
2
3
4
5
6
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);
}

当我们采用Integer a = 5;这样的赋值方式的时候,编译器会使用Integer中的valueOf方法自动装箱。

看上边代码第三行,数值i会与IntegerCache.low和IntegerCache.high进行比较。如果在这两个值之间,则返回一个已经存在的对象。

那么,我们顺着这条路走下去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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 &lt; cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}

Integer类中包含了一个内部类,这个内部类定义了low和high ,看最下边。

cache是一个Integer数组,包含了-128到大于127的int的包装对象。

也就是说,对象之间比较的确是内存的比较,只不过这里有一个坑,Integer保留了一个小范围空间的缓存对象数组,这样如果在小范围的使用Integr对象,就不需要频繁的开辟内存。

Boolean类默认也保存了true和false对象数组。

Byte256个对象全部保存

Short和Long范围和Integer范围相同。

坑:

在进行包含<,>的比较中,基本类型的包装对象会自动进行拆箱。

在switch语句中,包装对象也会进行自动拆箱,所以不会出现大数值比较不同的情况

String类型在switch语句中经过编译后会通过equals方法实现,所以也不会出现两个相同的字符串不相等的情况。