通常咱们使用数值时,都是使用基本类型,如int、long等,但若是你喜欢使用Integer、Long的包装类,那有一点可就得注意了。先来看下这段代码:缓存
/** * * @author trytocatch@163.com * @date 2014-2-12 */ public class AutoBoxingTest { public static final Integer CONST_A = 1; public static final Integer CONST_B = Integer.valueOf("2"); public static final Integer CONST_C = new Integer(3); private Integer status; public void setStatus(Integer status){ this.status = status; } public void displayStatus(){ if(status == CONST_A) System.out.println("It's CONST_A"); else if(status == CONST_B) System.out.println("It's CONST_B"); else if(status == CONST_C) System.out.println("It's CONST_C"); else System.out.println("Invalid status!"); } public static void main(String[] args) { AutoBoxingTest abt = new AutoBoxingTest(); abt.setStatus(1); abt.displayStatus(); abt.setStatus(2); abt.displayStatus(); abt.setStatus(3); abt.displayStatus(); } }
执行结果是(jre版本:1.7.0_10):this
It's CONST_A
It's CONST_B
Invalid status!编码
可能有人会奇怪,为何第三个不输出It's CONST_C呢?其实jre挺懒的,若是发现==两边都是对象,它就直接比较引用,而不是值,跟普通对象同样,由于status为3的那次比较中,两边是两个不一样的对象,因此不相同。而前两个为何能够呢?是由于IntegerCache的存在,在自动装箱(给CONST_A赋值和setStatus(int)时)和调用Integer.valueOf(String)时,返回的Integer有时(为何说是有时?是由于IntegerCache只对部分数值作了缓存,具体请阅读源码)是从Cache中获取的,因此都是同一个对象,而CONST_C在赋值时是咱们本身new出来的,因此跟Cache中的对象不是同一个。spa
延伸一下,若是一边是包装类,一边是基本类型时;或者使用了<、>、<=等比较符,都会进行值比较。只有恰好知足引用比较的条件时,jre才会偷懒,直接进行引用比较。因此,定义常量变量时,最好使用基本类型,使用==和!=时多多留意。code
ps:文章比较短,我不喜欢重复在网上随便都能搜到的东西,像装箱拆箱,封装等。若是本文对你有帮助,还请支持一下对象
再啰嗦几句,可能没细看的读者会以为,不就是说==比较的是引用么,有什么好讲的?我说下我写此文的考虑,由于平时可能习惯了直接对封装类使用<、>、<=等,使用==时也没出问题(上面的例子中CONST_A和CONST_B那两种状况),想固然的认为封装类不会进行引用比较,这种观念也许会在编码中埋下隐患,若是你将CONST_A的值改成10000,你会发现又不对了。blog