在java中 List list = new ArrayList(); 中 如果写为List<> list = new ArrayList(); 这样会报错的。 那么int 和Integer有什么区别呢??
我们知道int是基本数据类型,而Integer是int的包装类。这里就设计到了自动装箱和自动拆箱了,简单一点讲装箱就是基本数据类型自动转换为包装类,拆箱与之对应,包装类自动转换为基本数据类型。
//自动装箱
Integer s = 123;
//上面语句其实相当于这条语句
Integer ss = Integer.valueOf(123);
Integer s = 123自动将123装箱转换为包装类型。那么是如何实现自动装箱的呢,那就是执行了图中的第二条语句,看一下源码是如何实现的
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
可以看到首先会将参数会低值和高值比较(低值和高值在类中已给出,有兴趣可以看一下源码),低值low是-128,高值high是127。
如果参数大于等于-128 并且小于等于127则返回缓存中指定数据的包装类对象,否则返回一个新的对象。
比较一下代码,并判断一下
Integer a = 127;
Integer aa = 127;
Integer b = 128;
Integer bb = 128;
int aaa = 127;
int bbb = 128;
System.out.println(a == aa);
System.out.println(b == bb);
System.out.println(a == aaa);
System.out.println(b == bbb);
根据我们以前的想法,俩个数值相同 那么结果应该为true。但是执行结果并不是想象那样的。
可以看到在为127是结果和我们想象的一样,但是为128时却为false,在看一下上面我们所说的,在自动装箱时但基本数据类型数据大于127时返回的是一个新对象,所以这里Integer b和bb所指向的引用并不是同一个对象。所以结果为false,这也就是java中的128陷阱。如果想要相等那么一定要拆箱比较。
通过分析源码发现,只有double和float的自动装箱代码没有使用缓存,每次都是new 新的对象,其它的6种基本类型都使用了缓存策略。
使用缓存策略是因为,缓存的这些对象都是经常使用到的(如字符、-128至127之间的数字),防止每次自动装箱都创建一次对象的实例。
而double、float是浮点型的,没有特别的热的(经常使用到的)数据的,缓存效果没有其它几种类型使用效率高。