一般我们使用数值时,都是使用基本类型,如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中封装类的值比较的更多相关文章

  1. java中封装类(一)

    java中封装类共九个,分别是Boolean,Byte,Short,Integer,Long,Float,Double,Character,Void 其中Void对于使用者并无多大意义,也不可以构造任 ...

  2. java中,null值可以被强制转换为任何类型

    java中,null值可以被强制转换为任何类型

  3. Java中到底是值传递还是引用传递?

    Java中到底是值传递还是引用传递? 我们先回顾一下基本概念 实参和形参 参数在编程语言中是执行程序需要的数据,这个数据一般保存在变量中.在Java中定义一个方法时,可以定义一些参数, 举个例子: p ...

  4. Java中真的只有值传递么?

    Java中真的只有值传递么? (本文非引战或diss,只是说出自己的理解,欢迎摆正心态观看或探讨) 回顾值传递和引用传递 关于Java是值传递还是引用传递,网上有不一样的说法. 1.基本类型或基本类型 ...

  5. java中封装类(二)

    java中的数字类型包括 Byte,Short,Integer,Long,Float,Double.其中前四个是整数,后两个是浮点数. 在说java中数字类型之前先来看看它们统一的基类Number. ...

  6. java中两个值互换

    两个值互换有以下三种方式: 使用临时变量(此种方法便于理解) x = 10; y = 20; //begin int temp = x; x = y; y = temp; //end; //此时x = ...

  7. 2013年6月19日星期三java中函数地址值传递

    今天代码审核时确认了一个问题,理解了java中string和stringbuffer赋值问题,看到一个帖子很好,摘录如下: 理解这两个例子需要分清实参和形参的区别,引用和对象的区别 第一个例子的内部执 ...

  8. Java中的null值总结

    自我总结,有什么不对或不到位的地方,请指出,感激不尽! 目的:熟练掌握java中null值出现的情况,避免NullPointerException 代码环境准备:需要引入junit;将代码packag ...

  9. java中的参数传递——值传递、引用传递

    参数是按值而不是按引用传递的说明 Java 应用程序有且仅有的一种参数传递机制,即按值传递. 在 Java 应用程序中永远不会传递对象,而只传递对象引用.因此是按引用传递对象.Java 应用程序按引用 ...

随机推荐

  1. phthon

    没什么特别的,我们项目的跨平台代码都是在Windows环境下编码,然后跨平台编译调试,C++和Python代码都是如此.我们用C++实现底层和框架,用ctypes将纯C的API给Python化,然后用 ...

  2. java编码解码乱码问题

    服务器设值(中文)到界面使用了两次编码: String pageJson=URLEncoder.encode(URLEncoder.encode(str,"GBK"), " ...

  3. 为 Linux 应用程序编写 DLL[转]

    自:http://www.ibm.com/developerworks/cn/linux/sdk/dll/index.html 在仅仅只会编写插件的时候为什么要编写整个应用程序? 插件和 DLL 通常 ...

  4. HttpResponseMessage和HttpResponseException (转)

    Web API 中提供了 HttpResponseMessage 与 HttpResponseException 用于处理返回讯息,HttpResponseMessage 用于返回一个来自于客户端的请 ...

  5. [转]逻辑斯蒂回归 via python

    # -*- coding:UTF-8 -*-import numpydef loadDataSet(): return dataMat,labelMat def sigmoid(inX): retur ...

  6. thinkPHP--SQL连贯操作

    一.连贯入门 连贯操作使用起来非常简单,比如查找到 id 为 1,2,3,4 中按照创建时间的倒序的前两 位. //连贯操作入门 $user = M('User'); var_dump($user-& ...

  7. linux病毒

    linux病毒查杀规范 一.病毒发现 1.ps -A.ps -ef.ps -aux查看是否有异常进程 2.last,lastlog命令可查看最近登录的帐户及时间 3.查看/var/log/messag ...

  8. Nodejs学习(二)-express生成器

    1.安装生成器 sudo npm install express-generator -g 2.做ln链接,这个我就不介绍了,可以参照上个随笔,指向/usr/local/bin就行. 3.生成项目文件 ...

  9. PAMI 2010 Context-aware saliency detection

    This is a highly-cited paper. The context aware saliency proposed based on four principles, which ca ...

  10. 用ajax实现评论刷新

    前台代码: <script src="jquery-1.8.3.js"></script> <script type="text/javas ...