3

可能重复:
为什么 128==128 在此代码中返回 false 而 127==127 返回 true?

下面的一段 Java 代码返回 true

Integer i1=1;
Integer i2=1;
System.out.println(i1==i2);

那么我们在 Java 中拥有字符串字面量常量池概念的方式,在 Java 中的包装类的情况下是否也有类似的概念?

4

3 回答 3

8

Java 也有用于小整数之间的整数池,-128 to 127因此它对于整数的行为也与字符串常量池相似

您将在Integer课堂上找到以下代码

private static class IntegerCache {
    static final int high;
    static final Integer cache[];

    static {
        final int low = -128;

        // high value may be configured by property
        int h = 127;
        if (integerCacheHighPropValue != null) {
            // Use Long.decode here to avoid invoking methods that
            // require Integer's autoboxing cache to be initialized
            int i = Long.decode(integerCacheHighPropValue).intValue();
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - -low);
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }

    private IntegerCache() {}
}

也如毒药在下面的回答中所述:

第 5 章转换和促销

如果被装箱的值 p 是真、假、一个字节或 \u0000 到 \u007f 范围内的一个字符,或者一个介于 -128 和 127(包括)之间的 int 或短数字,则令 r1 和 r2 为p 的任意两个拳击转换。r1 == r2 总是如此。

于 2012-09-06T19:16:17.677 回答
2

对象池是 VM 和/或运行时环境的产物。出于性能原因,它们可能会在那里,但您永远不应该依赖它们。使用 .equals()。

JLS 指定了装箱行为,正如评论中向我指出的那样,这部分在 Integer 类本身中实现;但是,另一个有趣的注意事项是,即使这个池的大小也可以通过 VM 参数进行调整。从整数.java:

585       /**
586        * Cache to support the object identity semantics of autoboxing for values between
587        * -128 and 127 (inclusive) as required by JLS.
588        *
589        * The cache is initialized on first usage.  The size of the cache
590        * may be controlled by the -XX:AutoBoxCacheMax=<size> option.
591        * During VM initialization, java.lang.Integer.IntegerCache.high property
592        * may be set and saved in the private system properties in the
593        * sun.misc.VM class.
594        */
于 2012-09-06T19:17:04.140 回答
1

[5.1.7. 拳击转换] http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

被装箱的值 p 是 true、false、一个字节或一个在 \u0000 到 \u007f 范围内的字符,或者一个介于 -128 和 127(包括)之间的 int 或短数字,那么让 r1 和 r2 是任何的结果p的两次拳击转换。r1 == r2 总是如此。

但总的来说,依赖它是愚蠢的,因为您首先必须检查数字是否在缓存范围内,然后有条件地使用 == 或 equals()。对原始类型、类和枚举使用 ==,对其他所有类型使用等于。

于 2012-09-06T19:22:43.020 回答