小心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 应用程序按引用 ...
随机推荐
- 织梦系统“当前位置”{dede:field.position}的修改方法
dedecms中修改当前位置{dede:field.position},就是只要首页>一级栏目>二级栏目这样.找到include/typelink.class.php,找到这个文件里的这个 ...
- UIDynamicAnimator UIKit动力学
也许是工作上并没有这方面的需要,对UIDynamicAnimator的了解不多.这里做简单的介绍: UIKit动力学是模拟真实世界的一些特性,主要就是UIDynamicAnimator类,通过类中的不 ...
- CSV文件的规范
CSV文件,全程Comma-separated values,就是逗号分隔的数据文件.常用于数据集成的数据交换部分标准部分. 最近看到一个项目组在讨论接口文件CSV的规范,真是替他们着急.讨论点: 文 ...
- java正则随笔
一.string校验 要求字符串只能输入数字,字母大小写和‘@‘’‘.’‘_’三个特殊字符 public static boolean check1(String str){ String patte ...
- Java实现emf图片自己留转png(jpg)图片字节流
private byte[] emfToPng(InputStream is){ // InputStream inputStream=null; byte[] by=null; EMFInputSt ...
- webpack配置备份
package.json: { "name": "webpackTest", "version": "1.0.0", & ...
- RabbitMQ的work queue(2)
课堂上work queue没能很好的理解,看了大神的博客,顿觉醍醐灌顶,豁然开朗. work queue有两种模式: 平均分配:(默认)//channel.basicQos(1);即把 同一时刻服务器 ...
- sqllite
public static void tt() { int ID = 0; while(true) { stri ...
- Net通用进销存管理系统 + 开发文档+ 使用说明
通用进销存管理系统 + 开发文档+ 使用说明Net源码下载 包括下面的模块基础资料模块采购管理模块库存管理模块商务管理模块营业管理模块维修管理模块会员管理模块财务管理模块 Net通用进销存管理系统 + ...
- 【学习笔记】Y2-1-1 Oracle数据库基础
Oracle 简介关系型(二维表)数据库 用来存储海量数据在大数据量的并发检索的情况下,性能要高于其他同类数据库产品一般运行环境是Linux和UnixOracle版本中的I(Internet) G(G ...