一般我们使用数值时,都是使用基本类型,如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. Hibernate温习(一)

    //从学校出来几个月了,一直用maximo没有使用到Hibernate,趁着周末的空闲时间重新开始学习Hibernate. Hibernate概念: Hibernate是数据库访问层的框架,对JDBC ...

  2. 查看python api

    以下方法可以查看python 的api,包括selenium webdriver,requests等 1.cmd进入dos命令行窗口,输入python -m pydoc -p 2345   (2345 ...

  3. svn本地客户端和eclipse插件对应不上解决

    如果你是SVN来管理代码,如果你是用eclipse搞开发,如果你知道eclipse有SVN的插件,那么你一定想用它来直接管理你的代码.但是事情往往非人所愿.当我们用SVN客户端把代码更新到本地,并导入 ...

  4. wamp 配置遇到的问题

    /* 最近开发部署更换到国内的服务器,想来想去还是更换为wamp套件. 但是由于下的版本的都不太适合. 外网一直显示拒绝.排查问题之后 写个笔记做个记录 */ wamp You don't have ...

  5. 获取B表数据添加到A表中作为一个下拉列表元素存在

    1.ProductController类里toedit方法内添加: ProductModel product = ProductModel.dao.findById(id); //通过id查找服务类 ...

  6. Android Studio tips2

    Android不推荐把字符串进行硬编码,一般的做法是把字符串定义在laylout里,并在xml文件里对键值进行引用 例如<第一行代码>中 Hello word程序中"Hello ...

  7. win8 VB6打开提示MSCOMCTL.ocx未注册

    从xp上复制相应的文件到win8相应的位置,如果是不可以,win8中反注册此控件,再注册此控件

  8. C# 串口操作系列(3) -- 协议篇,二进制协议数据解析

    原文地址:http://blog.csdn.net/wuyazhe/article/details/5627253 我们的串口程序,除了通用的,进行串口监听收发的简单工具,大多都和下位机有关,这就需要 ...

  9. java中String、stringbuilder、stringbuffer区别

    1.可变与不可变 String类中使用字符数组保存字符串,如下就是,因为有"final"修饰符,所以可以知道string对象是不可变的.每次对String对象进行改变的时候其实都等 ...

  10. js 中闭包的概念