1、类型转换问题
JDK 1.5后 对基本数据类型提供了自动拆装箱方法, 我们再Integer对象与int类型互转时只需要一行代码来实现了
Integer a = 10; //自动装箱
int b = a; //自动拆箱
int c = 5;
Integer d = c; //自动装箱
System.out.println(b+",,"+d);
自动拆装箱都做了些什么,可以看一下编译后的class文件
Integer a = Integer.valueOf(10); //装箱
int b = a.intValue(); //拆箱
byte c = 5;
Integer d = Integer.valueOf(c);//装箱
System.out.println(b + ",," + d);
那么问题就来了 这里面的坑就是 Integer是对象,允许 null值出现,在拆箱时 一定要对Integer对象进行非空校验,否则 拆箱时就会报空指针异常了。
2、大小判断
Integer a = 189;
int d=189;
Integer b = 189;
Integer c = 199;
System.out.print("a>c");
System.out.println(a>c);
System.out.print("a==b");
System.out.println(a==b);
System.out.print("a==d");
System.out.println(a==d);
a>c false
a==b false
a==d true
这里面比较容易产生疑惑的就是 a和b都是189 为什么是false
编译后class内容
Integer a = Integer.valueOf(189); short d = 189; Integer b = Integer.valueOf(189); Integer c = Integer.valueOf(199); System.out.print("a>c"); System.out.println(a.intValue() > c.intValue()); System.out.print("a==b"); System.out.println(a == b); System.out.print("a==d"); System.out.println(a.intValue() == d);
这里可以看到 做不等判断时 Ingteger对象都进行了自动拆箱 以int类型进行比较 结果在预想之内
那么对比Integer对象判等 和 Integer对象与int数据类型判等的过程
与int类型判等时是先拆箱成了int类型,判等结果为true
区别在于 两个Integer对象 依旧是以Integer对象进行判等的,
这里分析一下Integer对象判等的问题
我们可以看下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); }这里会判断入参是否在
i >= IntegerCache.low && i <= IntegerCache.high
范围内,这个范围是什么呢?
看一下Integer对象的这个方法
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) { try { 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); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; 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; } private IntegerCache() {} }
在
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
这个java虚拟机配置(可自行配置)不大于127的情况下 是 -128 与127之间,拉回到
public static Integer valueOf(int i)
当我们定义的Integer对象在这个范围内时,会去从cache中取初始化好的对象,所以即使我们定义多个,也一直是同一个对象,地址永远相同,
而超过这个范围的Integer对象都是新new的Integer对象,每个对象的地址都不同,
恰巧 “==”运算符在比较对象时是比较的地址,所以造成了上面的不解
可以试一下
Integer a = 10 ;
Integer b = 10;
System.out.println(a==b);//true
Integer a = 200;
Integer b = 200;
System.out.println(a==b);//false