登录
首页 >  文章 >  java教程

Java包装类常量池与对象比较解析

时间:2026-04-12 20:43:43 358浏览 收藏

Java包装类的常量池机制让自动装箱对象的相等性判断充满陷阱:Byte、Short、Integer、Long、Character和Boolean在特定范围内会复用缓存对象,导致==比较有时返回true(如Integer a=100, b=100),但超出缓存范围或使用Float/Double时==必然失败;而equals()虽更可靠却需处理null和类型匹配问题——因此,真正安全又简洁的做法是统一用Objects.equals()进行判等,避开手动new、混用基本类型等常见误区,让你的代码既健壮又不易踩坑。

Java包装类常量池指南:如何判断两个自动装箱对象的相等性

Java中两个自动装箱的包装类对象是否相等,不能只看==equals()的结果,关键要看它们是否指向常量池中的同一对象,以及数值是否在缓存范围内。

包装类常量池只存在于Byte、Short、Integer、Long、Character和Boolean

Java为部分基本类型对应的包装类实现了缓存机制(常量池),但仅限以下六种:

  • Byte:全部值(-128 ~ 127)都缓存
  • Short:仅-128 ~ 127 缓存
  • Integer:默认-128 ~ 127 缓存(可通过-Djava.lang.Integer.IntegerCache.high=xxx调整上限)
  • Long:仅-128 ~ 127 缓存
  • Character:仅\u0000 ~ \u007F(即0~127)缓存
  • Boolean:仅truefalse两个实例缓存

注意:Float和Double没有常量池,每次自动装箱都会新建对象。

用==比较时,本质是判断是否引用同一对象

当两个自动装箱变量的值落在缓存范围内,==可能返回true;超出范围则一定为false(除非巧合指向同一个新对象,但不可依赖):

Integer a = 100;    // 缓存内 → 指向常量池中同一个Integer对象
Integer b = 100;
System.out.println(a == b); // true

Integer c = 200;    // 超出默认缓存范围 → 各自new Integer(200)
Integer d = 200;
System.out.println(c == d); // false

// Boolean例外:只有true/false两个实例,所以总是true
Boolean x = true, y = true;
System.out.println(x == y); // true

用equals()比较更安全,但要注意null和类型

equals()会先判空、再比类型、最后比数值,适合大多数场景:

  • 对同一类型包装类调用equals(),结果稳定且符合数值语义
  • 不同包装类型之间调用(如Integer.equals(Long))返回false(类型不匹配)
  • 任一操作数为null时,equals()返回false(不会NPE)

推荐写法:Objects.equals(a, b),它内部已处理null安全问题。

避免陷阱:手动new和混用基本类型

以下写法绕过常量池,容易引发误判:

  • Integer i = new Integer(100) → 总是新建对象,==必为false
  • int primitive = 100; Integer boxed = 100; System.out.println(primitive == boxed); → 会触发自动拆箱,实际比较的是int == int,结果正确但逻辑隐晦

统一建议:优先使用自动装箱(Integer i = 100),比较时用Objects.equals(a, b),避免==用于包装类对象判等。

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《Java包装类常量池与对象比较解析》文章吧,也可关注golang学习网公众号了解相关技术文章。

资料下载
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>