java 引入包装类型,是为了解决基本类型实例化问题,以便让一个基本类型也能参与到面向对象的编程世界中。而在java5中,泛型更是对基本类型说了“不”。
1、谨慎包装类型null值
如果想把整型放在list中,则必须使用Integer包装类型 。
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add(20);
list.add(null);
f(list);
}
public static int f(List<Integer> list){
int count = 0;
for(int i : list){
count += i;
}
return count;
}
运行失败,NullPointException , 我们知道 for循环时候,会进行自动拆箱的过程,也就是会调用Integer.intValue();由于包装对象是null值,所以就是空异常。 修改很简单加入null值检查。
可以这样改进下,加上 null值校验。对于此类问题,我们只需谨记一点,包装类型参与计算,一定要进行null值校验。
public static int f1(List<Integer> list){
int count = 0;
for(Integer i : list){
count += (i == null) ? 0 : i.intValue();
}
return count;
}
2、谨慎包装类型的大小比较
Integer i = new Integer(100);
Integer j = new Integer(100);
System.out.println(i == j);
System.out.println(i > j);
System.out.println(i < j);
System.out.println(i.equals(j));
java 中 “== ”是用来判断两个操作数是否相等,如果是基本数据类型,则判断值是否相等,如果是对象则判断是否同一个引用,也就是地址是否相等,这里明显是两个地址,两个对象,不可能相等。
java 中 “<”,“>"是判断两个数字类型的大小关系,注意只能是数字类型的大小比较,对于Integer包装类型,是根据其intvalue(),方法的返回值进行比较的。问题清楚了。
直接使用Integer的 compareTo方法即可 。只要是两个对象进行比较,就应该采用相应的方法,而不是通过java的默认机制来处理,除非你确定对此非常理解。
3、优先使用整型池
//在-128~127 之外的数
Integer i1 = 200;
Integer i2 = 200;
System.out.println("i1==i2: "+(i1==i2));
// 在-128~127 之内的数
Integer i3 = 100;
Integer i4 = 100;
System.out.println("i3==i4: "+(i3==i4));
false true .
在自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,
所以范例中,i3 与 i4实际上参考至同一个对象。
如果超过了从–128到127之间的值,被装箱后的Integer对象并不会被重用,
即相当于每次装箱时都新建一个 Integer对象,所以范例中,i1与i2参考的是不同的对象。
自动拆箱 也是调用了 Integer.valueOf(); 下面是 源码: 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);
}