网站首页 > java教程 正文
今天来谈谈在Java中可能会让你感到惊讶的事情——为什么有时用==比较数字的行为并不像你期望的那样。
你可能会认为,在Java中比较两个数字时只要值相等它总是会返回true,因为两边的数字都是一样的,对吧?事实证明,在Java中并不总是那么简单。
一个小代码片段来说明这一点:
Integer a = 128;
Integer b = 128;
System.out.println(a == b); // false
Integer x = 1;
Integer y = 1;
System.out.println(x == y); // true
现在来解释一下为什么会发生这种情况,这与Java中的整数缓存有关。深入探讨下。
在Java中,对于基本数据类型(如int、char等)的比较,使用的是值比较。而对于对象(如Integer),使用的是引用比较,即比较的是两个引用是否指向同一个对象。然而,对于Integer类型,Java进行了一些特殊的优化,这影响了比较的结果,特别是在自动装箱和拆箱时。
分析
- 基本数据类型的比较:
- 对于基本数据类型int,1 == 1直接比较的是两个值,因此结果为true。
- Integer对象的比较:
- Java中的Integer类是一个对象包装类,用于包装基本数据类型int的值。
- 当使用Integer变量进行比较时(如a == b),比较的是两个对象的引用是否相同,而不是它们包装的值。
- 然而,Java对Integer类进行了优化,对于值在-128到127之间的Integer对象,Java会缓存这些对象,即当你使用自动装箱(如Integer a = 127;)时,如果值在这个范围内,Java会返回缓存中的对象,而不是创建一个新的对象。
基于享元模式的整数缓存魔力
Integer类在Java中使用了享元模式(Flyweight Pattern)这一设计模式。享元模式是一种对象结构型模式,它运用共享技术有效地支持大量细粒度对象的复用。在享元模式中,由于存在大量的细粒度对象,如果直接创建这些对象,可能会导致内存占用过高,性能下降。因此,享元模式通过共享对象来减少对象的数量,从而降低内存占用,提高性能。
具体说,Integer类在Java中实现了对-128到127之间整数的缓存。当创建这些范围内的Integer对象时,Integer类会返回缓存中的对象,而不是创建一个新的对象。这样做可以大大减少对象的创建数量,提高内存利用率和性能。这种缓存机制正是享元模式的一种应用。
具体情况分析
- 对于Integer a = 128; Integer b = 128;:
- 因为128不在-128到127的缓存范围内,所以a和b分别指向了两个不同的Integer对象,尽管它们的值都是128。
- 因此,a == b比较的是两个对象的引用,它们不同,所以结果为false。
- 对于Integer x = 1; Integer y = 1;:
- 因为1在-128到127的缓存范围内,所以x和y都指向了缓存中的同一个Integer对象。
- 因此,x == y比较的是两个对象的引用,它们相同(指向同一个对象),所以结果为true。
如何正确比较Integer对象
- 想要比较两个Integer对象所包装的值,而不是它们的引用,应该使用equals()方法:Integer a = 128;
Integer b = 128;
System.out.println(a.equals(b)); // true,因为比较的是值 - 使用equals()方法可以确保无论Integer对象的值是否在缓存范围内,比较的结果都是基于它们的值,而不是引用。
最后
- 对于基本数据类型(如int),==操作符比较的是值。
- 对于对象(如Integer),==操作符比较的是引用。
- Java对Integer对象进行了缓存优化,对于-128到127之间的值,会返回缓存中的对象。
- 为了正确比较Integer对象所包装的值,应使用equals()方法。
猜你喜欢
- 2024-10-29 Java高级程序员(5年左右)面试题目集
- 2024-10-29 Java编程实现数字签名(java签名验签的做法)
- 2024-10-29 Java数组中重复的数字(java数组重组)
- 2024-10-29 Java控制台猜数字游戏(javaweb猜数字游戏)
- 2024-10-29 如何基于Java解析国密数字证书(java 国密算法库)
- 2024-10-29 Java修炼终极指南:22. 简要介绍Java中的(无)符号整数
- 2024-10-29 Java 枚举获取值和数字下标(java枚举类根据key获取value)
- 2024-10-29 关于数字的对齐原来这么简单(excel中数字的对齐方式)
- 2024-10-29 一文带你搞懂Java异常(java异常简单理解)
- 2024-10-29 入门java打卡第五天——number&math类
你 发表评论:
欢迎- 07-15采用Oracle OSB总线进行服务注册和接入
- 07-15javaEE 新闻管理系统 oracle11+tomcat6
- 07-15从Oracle演进看数据库技术的发展(oracle数据库发展史)
- 07-15如何升级oracle数据库安全补丁(oraclepsu补丁升级)
- 07-15【权威发布】关于Oracle WebLogic Server未授权远程代码执行高危漏洞的预警通报
- 07-15【mykit-data】 数据库同步工具(数据库表同步工具)
- 07-15[Java速成] 数据库基础,Connector/J、JDBC、JPA的关系(day 7)
- 07-15Google前工程主管“入住”Oracle(google浏览器找不到以前的书签)
- 最近发表
-
- 采用Oracle OSB总线进行服务注册和接入
- javaEE 新闻管理系统 oracle11+tomcat6
- 从Oracle演进看数据库技术的发展(oracle数据库发展史)
- 如何升级oracle数据库安全补丁(oraclepsu补丁升级)
- 【权威发布】关于Oracle WebLogic Server未授权远程代码执行高危漏洞的预警通报
- 【mykit-data】 数据库同步工具(数据库表同步工具)
- [Java速成] 数据库基础,Connector/J、JDBC、JPA的关系(day 7)
- Google前工程主管“入住”Oracle(google浏览器找不到以前的书签)
- Oracle数据库云服务系列新增前所未有的企业级功能
- 直播预告丨如何实现Oracle存储过程到java的一键转化
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)