最近在开发中的时候,在使用数据比较的时候。总是出现预想之外的结果。排查的时候,很容易忽略 。经过一番深究,总算有点体会了!!
我们都知道在java中数据有8种基本数据类型及其包装类
1、基本类型:byte 二进制位数:8
2、包装类:java.lang.Byte
3、最小值:Byte.MIN_VALUE=-128
4、最大值:Byte.MAX_VALUE=127
5、
6、基本类型:short 二进制位数:16
7、包装类:java.lang.Short
8、最小值:Short.MIN_VALUE=-32768
9、最大值:Short.MAX_VALUE=32767
10、
11、基本类型:int 二进制位数:32
12、包装类:java.lang.Integer
13、最小值:Integer.MIN_VALUE=-2147483648
14、最大值:Integer.MAX_VALUE=2147483647
15、
16、基本类型:long 二进制位数:64
17、包装类:java.lang.Long
18、最小值:Long.MIN_VALUE=-9223372036854775808
19、最大值:Long.MAX_VALUE=9223372036854775807
20、
21、基本类型:float 二进制位数:32
22、包装类:java.lang.Float
23、最小值:Float.MIN_VALUE=1.4E-45
24、最大值:Float.MAX_VALUE=3.4028235E38
25、
26、基本类型:double 二进制位数:64
27、包装类:java.lang.Double
28、最小值:Double.MIN_VALUE=4.9E-324
29、最大值:Double.MAX_VALUE=1.7976931348623157E308
30、
31、基本类型:char 二进制位数:16
32、包装类:java.lang.Character
33、最小值:Character.MIN_VALUE=0
34、最大值:Character.MAX_VALUE=65535
这里以int和Integer来做说明。 2者之间最显著的区别在于Integer可以为null,而int不能。所以在开发中,多使用包装类作为方法的参数。
这时,如果用 == 比较2个Integer的值。就很容易出现问题了~~~~~~~~~~~~~
Integer a = 5; Integer b = 5;
a == b ---------> True
这里这2个包装类在使用的使用,因为2个值指向同一个对象。所以比较时是true,而输出时会自动拆箱,所以System.out.print(a)会 是 5 而不是一个地址(对象)
但是:
Integer a = 500; Integer b = 500;
a == b ---------> false
System.out.print(a)会 是一个地址(而不是500)
因为这时没有拆箱的操作。 在进行装箱的时候。通过源码可知 int类型的装箱拆箱的范围必须在[-128,127];
public static Integer valueOf(int i) {
if(i >= -128 && i <= IntegerCache.high)
return IntegerCache.cache[i + 128];
else
return new Integer(i);
}
而其中IntegerCache类的实现为:
private static class IntegerCache {
static final int high;
static final Integer cache[];
static {
final int low = -128;
// high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
从这2段代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。
所以,在进行包装类比较的时候,如果拿不准数值的范围,最好手动拆箱成基本类型
Integer a = 500; Integer b = 500;
a.intValue() == b.intValue() ---------> True
System.out.print(a)会 是一个地址(而不是500)