深刻了解java自动装箱和拆箱

今天看《深刻理解JAVA虚拟机》,发现本身对自动装箱和拆箱有一些误解,在此写下来:缓存

问题一、code

Integer a = 3; 

Integer b = 3;

请问 a==b 返回 true 仍是 false ?对象

开始坚决果断选择了false ,明显 a和b不是同一个对象。结果亲自运行这段代码发现返回true。源码

问题二、虚拟机

Integer c = 333; 
Integer d= 333;

请问 c==d 返回 true 仍是 false ?it

亲自试验以后问题2返回false。c.equals(d) 返回true。变量

不解了吧?若是问题1返回true,问题2为何返回false呢?方法

首先说下自动装箱:Integer自动装箱时是调用valueOf(int i)来完成自动装箱的,再来看Integer的valueOf(int i)的源码:总结

public static Integer valueOf(int i) { final int offset = 128; if (i >= -128 && i <= 127) { // must cache return IntegerCache.cache[i + offset]; } return new Integer(i); }static

原来-128-127之间的整数返回的是缓存,大于这个区间的才返回新的Integer对象。

再来看看Integer的equals方法:

public boolean equals(Object obj) { if (obj instanceof Integer) { return value == ((Integer)obj).intValue(); } return false; } 不难看出Integer对象的equals方法比较的是Integer拆箱以后的值。自动拆箱是调用initValue方法来实现的。

总结:对于基本类型的包装类型,Byte、Short、Integer、Long、Character 都存在这样的缓存机制,你们在使用字面量初始化对象,而后进行== 比较的时候须要留心注意。 Float、Double没有这样的机制。 Boolean 比较特殊,字面量的初始化后,== 操做会返回Boolean类静态变量的计较,也能够当作一种缓存吧。

相关文章
相关标签/搜索