一般我们使用数值时,都是使用基本类型,如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,你会发现又不对了。

转载于:https://www.cnblogs.com/trytocatch/p/3545244.html

小心Java中封装类的值比较相关推荐

  1. java 中封装类有哪些_java中封装类(一)

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

  2. Java中传参数--值传递和引用传递

    ** Java中传参数–值传递和引用传递 ** 在Java中,传参数分为值传递和引用传递. 在Java中的数据类型分为两大类:一类是引用类型,也叫类类型(除了String以外的所有复合数据类型,包括数 ...

  3. Java中只存在值传递

    2019独角兽企业重金招聘Python工程师标准>>> 在Java中并不存在引用传递(即地址传递),对于变量(可以是基本数据类型,也可以是引用数据类型)而言,可以理解为就是一个地址. ...

  4. java中的返回值到底有什么用?

    今天看到一个有意思的问题:java中的返回值到底有什么用? 看到了一个高赞回答如下: 你是公司的老总,然后你跟你秘书说,我想要两张的电影票.然后,你秘书去排队买票,最后把两张电影票给你,这两张电影票就 ...

  5. java中hashcode_浅谈Java中的Hash值

    1.Hash值有什么用? HashMap.HashTable.HashSet,所以涉及到使用Hash值进行优化存储的地方,都会用到HashCode.HashCode是Key,这种计算为提高计算的性能. ...

  6. 如何从Java中的字符串值获取枚举值?

    说我有一个枚举 public enum Blah {A, B, C, D } 我想找到一个字符串的枚举值,例如"A"就是Blah.A 怎么可能做到这一点? Enum.valueOf ...

  7. 结构为键值的map_在Java中增加Map值的最有效方法-只需搜索键一次

    结构为键值的map 这个问题可能被认为太基础了,但是在论坛中经常被问到. 在本文中,我将讨论一种仅在Map ONCE中搜索键的方法. 让我们首先来看一个例子. 假设我正在使用Map创建一个字符串频率列 ...

  8. [转载] 由swap引出的java中参数严格值传递问题

    参考链接: Java严格按照值传递 [size=large]博文出处:http://atleeon.com/code/2013/11/28/java-swap-value/ [/size] 晚上看到一 ...

  9. Java中哈希值是怎么算的

    最近被提及Java中HashMap的一些实现及哈希冲突等,不知不觉就想到哈希值到底是怎么计算出来的,正文如下. 结论: 对于String.Integer等类复写了Object中的hashCode方法的 ...

  10. Java中的Hash值到底是怎么计算的

    最近被提及Java中HashMap的一些实现及哈希冲突等,不知不觉就想到哈希值到底是怎么计算出来的,正文如下. 结论: 对于String.Integer等类复写了Object中的hashCode方法的 ...

最新文章

  1. Mysql中设置默认时间为当前值
  2. linux下如何使用USB转串口设备
  3. 从阿里云下载图片到本地
  4. vue工程全局设置ajax的等待动效
  5. 批量删除html网页,批量删除.html · panghuamama/Clearly Local - Gitee.com
  6. 四五六年级计算机教学计划,五六年级信息技术教学计划
  7. JAVA Web基础3-Servlet
  8. 2010年6月16日最新NOD32激活码和升级ID(含ESS/EAV)
  9. python爬取b站up主粉丝信息_使用Python爬取B站数据
  10. 2018年阿里巴巴前端开源项目汇总
  11. Quartus-II 13.1 详细安装、注册、配置步骤
  12. JAMF的NetBoot/SUS Appliance
  13. 想查看实时卫星影像?最近一周就不错了
  14. 这些地区的大学,取消英语四六级口语考试!
  15. CG100具体功能介绍
  16. GPU渲染管线与可编程着色器
  17. 宏病毒的研究与实例分析02——复合文档格式分析
  18. chapter10 十大算法
  19. 一窥深度学习黑箱,拼接深层神经网络架构
  20. Latex文本两端对齐

热门文章

  1. 【学习笔记】平衡二叉树(AVL树)简介及其查找、插入、建立操作的实现
  2. linux打开文件程序,linux – 获取打开特定文件的应用程序列表
  3. java用io流存信息_Java io流的学习
  4. [codeup 1126]看电视
  5. 什么是java OOM Out Of Memory 内存溢出?如何分析及解决oom问题?
  6. Criteo数据集探索
  7. 2021-09-08173. 二叉搜索树迭代器 栈
  8. C++ OS 网络 数据库 (面试)
  9. 多路复用增益,PASTA定理
  10. linux嵌入式6818,嵌入式ARM实验箱(FS_6818M4)_华清远见研发中心