Java整数的内存分配

6

嘿,我正在尝试理解以下代码片段。

public static void main(String[] args) {
    Integer i1 = 1000;
    Integer i2 = 1000;
    if(i1 != i2) System.out.println("different objects");
    if(i1.equals(i2)) System.out.println("meaningfully equal");
    Integer i3 = 10;
    Integer i4 = 10;
    if(i3 == i4) System.out.println("same object");
    if(i3.equals(i4)) System.out.println("meaningfully equal");
}

这种方法运行所有的println指令。即使i1 != i2为真,但i3 == i4。乍一看,这让我感到奇怪,它们应该作为引用都是不同的。我可以想出一个解释,如果我将相同的byte值(-128到127)传递给i3和i4,则它们始终相等作为引用,但任何其他值都会使它们不同。
我无法解释这个问题,你能否指向一些文档或提供一些有用的见解?
谢谢
3个回答

13

int值自动装箱为Integer对象时,会对常见值使用缓存(正如您所确定的那样)。这在JLS at §5.1.7 Boxing Conversion中有规定:

如果被装箱的值ptruefalsebytechar(范围在\u0000\u007f之间)、或者介于-128127之间的shortint数字,则令r1r2分别为任意两个p的装箱转换结果。始终满足r1 == r2

请注意,这仅在语言自动为您装箱一个值时,或者当您使用Integer.valueOf()时才会应用此规则。使用new Integer(int)始终生成一个新的Integer对象。

小提示:JVM实现也可以自由地缓存那些范围之外的值,因为相反的情况没有规定。但是,我还没有看到这样的实现。


2

Java会保留-128到128之间的Integer对象池。如果您在这个范围之外使用Integer,将会创建新的Integer对象。这就是解释。

在Java源代码中,您可以看到它:

public static Integer valueOf(int i) {
        if(i >= -128 && i <= IntegerCache.high)
            return IntegerCache.cache[i + 128];
        else
            return new Integer(i);
    }

在 Integer 上下文中使用的 int 字面量是否会使用 Integer.valueOf(...) 转换,而不是 new Integer(...) - Cruncher

1

从-128到127的整数被包装成固定对象。这就是为什么你会得到i3 == i4的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接