小心Java中封装类的值比较
一般我们使用数值时,都是使用基本类型,如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):
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中的对象不是同一个。
延伸一下,如果一边是包装类,一边是基本类型时;或者使用了<、>、<=等比较符,都会进行值比较。只有刚好满足引用比较的条件时,jre才会偷懒,直接进行引用比较。所以,定义常量变量时,最好使用基本类型,使用==和!=时多多留意。
ps:文章比较短,我不喜欢重复在网上随便都能搜到的东西,像装箱拆箱,封装等。如果本文对你有帮助,还请支持一下
再啰嗦几句,可能没细看的读者会觉得,不就是说==比较的是引用么,有什么好讲的?我说下我写此文的考虑,因为平时可能习惯了直接对封装类使用<、>、<=等,使用==时也没出问题(上面的例子中CONST_A和CONST_B那两种情况),想当然的认为封装类不会进行引用比较,这种观念也许会在编码中埋下隐患,如果你将CONST_A的值改为10000,你会发现又不对了。
小心Java中封装类的值比较的更多相关文章
- java中封装类(一)
java中封装类共九个,分别是Boolean,Byte,Short,Integer,Long,Float,Double,Character,Void 其中Void对于使用者并无多大意义,也不可以构造任 ...
- java中,null值可以被强制转换为任何类型
java中,null值可以被强制转换为任何类型
- Java中到底是值传递还是引用传递?
Java中到底是值传递还是引用传递? 我们先回顾一下基本概念 实参和形参 参数在编程语言中是执行程序需要的数据,这个数据一般保存在变量中.在Java中定义一个方法时,可以定义一些参数, 举个例子: p ...
- Java中真的只有值传递么?
Java中真的只有值传递么? (本文非引战或diss,只是说出自己的理解,欢迎摆正心态观看或探讨) 回顾值传递和引用传递 关于Java是值传递还是引用传递,网上有不一样的说法. 1.基本类型或基本类型 ...
- java中封装类(二)
java中的数字类型包括 Byte,Short,Integer,Long,Float,Double.其中前四个是整数,后两个是浮点数. 在说java中数字类型之前先来看看它们统一的基类Number. ...
- java中两个值互换
两个值互换有以下三种方式: 使用临时变量(此种方法便于理解) x = 10; y = 20; //begin int temp = x; x = y; y = temp; //end; //此时x = ...
- 2013年6月19日星期三java中函数地址值传递
今天代码审核时确认了一个问题,理解了java中string和stringbuffer赋值问题,看到一个帖子很好,摘录如下: 理解这两个例子需要分清实参和形参的区别,引用和对象的区别 第一个例子的内部执 ...
- Java中的null值总结
自我总结,有什么不对或不到位的地方,请指出,感激不尽! 目的:熟练掌握java中null值出现的情况,避免NullPointerException 代码环境准备:需要引入junit;将代码packag ...
- java中的参数传递——值传递、引用传递
参数是按值而不是按引用传递的说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递. 在 Java 应用程序中永远不会传递对象,而只传递对象引用.因此是按引用传递对象.Java 应用程序按引用 ...
随机推荐
- bash 相关的一些小代码片断
批量修改文件名: for i in *.html; do mv $i ${i/oldstring/newstring}; done; 批量替换文件内容: sed -i "s/oldstrin ...
- Ninject之旅之五:Ninject XML配置
摘要 使用XML配置,需要添加Ninject XML扩展的引用.下一步是添加一个或多个包含类型注册的XML文件.记得这些文件应该跟应用程序一起发布.因此不要忘记将XML文件的属性设置成“Copy if ...
- 答:SQLServer DBA 三十问之六:Job信息我们可以通过哪些表获取;系统正在运行的语句可以通过哪些视图获取;如何获取某个T-SQL语句的IO、Time等信息;
6. Job信息我们可以通过哪些表获取:系统正在运行的语句可以通过哪些视图获取:如何获取某个T-SQL语句的IO.Time等信息: 我的MSDB数据库中有全部的表: sys.all_columns,s ...
- AKKA(一)认知AKKA
Akka 是一个用 Scala 编写的库,用于简化编写容错的.高可伸缩性的 Java 和 Scala 的 Actor 模型应用.它已经成功运用在电信行业.系统几乎不会宕机(高可用性 99.999999 ...
- css左右居中的几种常见方法
本人是前端的新人,这是第一次写技术博客,各位大大,本文有错误请指正,手中的板砖尽量轻拍,我怕疼~~ 对于水平居中和垂直居中我也用过很多方法,但是有的时候管用有的时候又嗝屁不好使了.涉及到的情况很多,所 ...
- disconf系列【2】——解决zk部署情况为空的问题
如下图所示,在安装完成之后,发现zk(zookeeper)部署情况为空. 注:承接上篇,环境未发生改变. 1.解决zk没有启动的问题 查看disconf日志,发现zk没有启动. 实际情况是:zk已经启 ...
- LDO和DC-DC器件的区别
DCDC的意思是直流变(到)直流(不同直流电源值的转换),只要符合这个定义都可以叫DCDC转换器,包括LDO.但是一般的说法是把直流变(到)直流由开关方式实现的器件叫DCDC. LDO 是低 ...
- pooling的原理与Python实现
本文首先阐述pooling所对应的操作,然后分析pooling背后蕴含的一些道理,最后给出pooling的Python实现. 一.pooling所对应的操作 首先从整体上对pooling有一个直观的概 ...
- 在使用dot。js中的值中有空格出现后,进行去除
title= {{= x.replace(/ /g,' ') 通过replace将数据进行处理再展示
- 数据转移发现font有问题
本地正常 以为是mime.types没有 但是发现是存在的 然后根据提示百度了很久都没有解决 解决: 去字体官网下载改字体文件下来 上传到服务器 发现可以正常访问 说明不是服务器的问题 有个提示 i ...