🍅 作者简介:哪吒,CSDN2021博客之星亚军🏆、新星计划导师✌、博客专家💪
🍅 哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师
🍅 技术交流:定期更新Java硬核干货,不定期送书活动
🍅 关注公众号【哪吒编程】,回复 1024 ,获取《10万字208道Java经典面试题总结(附答案)》2024修订版pdf,背题更方便,一文在手,面试我有
目录
- 一、new Integer("127")
- 二、Integer.valueOf("128")
- 三、主要区别
- 1、对象创建
- 2、缓存使用
- 3、性能和内存:
- 4、值的考虑:
- 四、对比示例
- 五、为什么说Integer.valueOf("128") 也不使用缓存,是因为超出了范围?
- 1、Integer 缓存是什么?
- 2、为什么是 -128 到 127?
- 3、为什么 128 不在缓存中?
- 4、代码示例
- 5、可以改变缓存范围吗?
- 6、Integer对象比较
- 六、结论
听到这个问题的一瞬间,我的第一反应是:“口误吧?127和128肯定不一样啊~”,哈哈,你的呢?
其实这是一道大厂经典面试题,它触及了 Java 中 Integer 对象的创建和缓存机制的一个微妙之处。
一、new Integer(“127”)
- 总是在堆内存中创建一个新的 Integer 对象。
- 值为 127。
- 不使用整数缓存池。
二、Integer.valueOf(“128”)
- 创建一个新的 Integer 对象,值为 128。
- 不使用整数缓存池,因为 128 超出了默认缓存范围。
三、主要区别
1、对象创建
两种方式在这个例子中都会创建新对象。
2、缓存使用
new Integer(“127”) 不使用缓存。
Integer.valueOf(“128”) 也不使用缓存,但原因不同(超出范围)。
3、性能和内存:
在这个特定例子中,两者的性能和内存使用基本相同。
4、值的考虑:
127 在缓存范围内,但 new 关键字绕过了缓存。
128 超出缓存范围,所以 valueOf 方法会创建新对象。
四、对比示例
Integer a = new Integer("127");
Integer b = new Integer("127");
System.out.println(a == b); // false
Integer c = Integer.valueOf("127");
Integer d = Integer.valueOf("127");
System.out.println(c == d); // true
Integer e = Integer.valueOf("128");
Integer f = Integer.valueOf("128");
System.out.println(e == f); // false
五、为什么说Integer.valueOf(“128”) 也不使用缓存,是因为超出了范围?
1、Integer 缓存是什么?
Java 的 Integer 类维护了一个内部缓存,用于存储经常使用的整数值。这个缓存就像一个预先准备好的数字集合。
默认情况下,这个缓存包含了 -128 到 127 之间的所有整数。
这个范围是经过 Java 开发者仔细考虑后选定的,因为这个范围内的数字在日常编程中使用频率最高。
2、为什么是 -128 到 127?
- 字节范围: 这个范围恰好对应一个字节(byte)可以表示的整数范围。
- 常用数字: 大多数日常计算和循环中使用的小整数都在这个范围内。
- 内存权衡: 缓存范围不能太大,否则会占用过多内存。
3、为什么 128 不在缓存中?
128 刚好超出了这个预定义的范围。
当你调用 Integer.valueOf(“128”) 时,Java 会检查这个数字是否在缓存范围内。
发现 128 超出范围后,Java 就会创建一个新的 Integer 对象,而不是使用缓存。
4、代码示例
Integer a = Integer.valueOf("127"); // 使用缓存
Integer b = Integer.valueOf("127"); // 使用缓存
System.out.println(a == b); // 输出 true,因为是同一个缓存对象
Integer c = Integer.valueOf("128"); // 不使用缓存,创建新对象
Integer d = Integer.valueOf("128"); // 不使用缓存,再次创建新对象
System.out.println(c == d); // 输出 false,因为是两个不同的对象
5、可以改变缓存范围吗?
是的,可以通过 JVM 参数 -XX:AutoBoxCacheMax= 来增加上限。
但是,下限 -128 是固定的,不能改变。
6、Integer对象比较
不要依赖于缓存机制来比较整数对象。
始终使用 .equals() 方法来比较 Integer 对象的值。
六、结论
虽然在给定的例子中(“127” 和 “128”),两种方法都会创建新对象,但它们的行为原因不同:
new Integer(“127”) 总是创建新对象,无论值是多少。
Integer.valueOf(“128”) 创建新对象是因为 128 超出了缓存范围。
在实际应用中,除非特别需要新对象,否则推荐使用 Integer.valueOf() 或自动装箱,以便在可能的情况下利用缓存优化。
虽然了解这些细节很重要,但在日常编程中,我们应该专注于编写清晰、正确的代码,而不是过度依赖于这些底层优化。正确使用 .equals() 进行值比较,以及优先使用 valueOf() 或自动装箱,通常就足以编写高效且可靠的代码。
👉 GPT功能:
- GPT-4o知识问答:支持1000+token上下文记忆功能
- 最强代码大模型Code Copilot:代码自动补全、代码优化建议、代码重构等
- DALL-E AI绘画:AI绘画 + 剪辑 = 自媒体新时代
- 私信哪吒,直接使用GPT-4o
🏆文章收录于:100天精通Java从入门到就业
哪吒数年工作总结之结晶。
🏆哪吒多年工作总结:Java学习路线总结,搬砖工逆袭Java架构师。
华为OD机试 2023B卷题库疯狂收录中,刷题点这里
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,发现新题目,随时更新,全天CSDN在线答疑。