为何Java中超出Byte范围的Integer对象不指向同一内存地址?
Java Integer对象缓存机制详解
这个问题其实涉及到Java Integer类的缓存优化机制,我来给你拆解清楚:
你观察到的现象完全符合Java的设计逻辑——当Integer的值落在-128到127这个Byte范围内时,自动装箱创建的对象会复用缓存里的实例,所以用==比较内存地址会返回true;超出这个范围后,每次装箱都会创建新的Integer对象,这时==比较地址就会返回false,但equals()方法因为比较的是实际数值,所以始终返回true。
背后的原理:IntegerCache静态缓存
Java的Integer类内部维护了一个名为IntegerCache的静态内部类,它会在Integer类加载时,预先创建好-128到127之间的所有Integer对象,并把它们存储在一个数组中。当你使用Integer x = 10;这种自动装箱语法时,底层会调用Integer.valueOf(int)方法,这个方法的逻辑是:
- 如果传入的int值在缓存范围内,直接返回缓存数组里的对应对象
- 如果超出范围,则创建一个新的Integer对象返回
代码示例验证
缓存范围内的情况:
Integer x = 10; Integer y = 10; System.out.println(x.equals(y) + " " + (x==y)); // 输出 true true
超出缓存范围的情况:
Integer x = -129; Integer y = -129; System.out.println(x.equals(y) + " " + (x==y)); // 输出 true false
补充说明
- 缓存的下限-128是固定不可修改的,但上限127可以通过JVM启动参数
-XX:AutoBoxCacheMax=<自定义大小>来调整,不过一般不建议随意修改,因为这个范围是Java团队根据日常开发的使用频率确定的最优值。 - 一定要注意:
==对于引用类型比较的是内存地址,而Integer重写了equals()方法,比较的是实际的int数值,这就是为什么两种场景下equals()都返回true的原因。
内容的提问来源于stack exchange,提问作者Prime72
相关产品推荐
相关产品推荐

