Java中Wrapper类的行为

时间:2012-09-06 19:14:57

标签: java wrapper

  

可能重复:
  Why does 128==128 return false but 127==127 return true in this code?

下面的Java代码返回true

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

所以我们在Java中使用String文字常量池的概念的方式,在Java中包装类的情况下是否也有类似的概念?

3 个答案:

答案 0 :(得分:8)

Java还为-128 to 127之间的小整数设置了整数池,因此它对于Integer也会表现相同,也类似于String Constant pool

您可以在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() {}
}

同样如下面陈述毒药:

Chapter 5. Conversions and Promotions

  

如果被装箱的值p为真,假,字节或范围为\ u0000到\ u007f的字符,或者介于-128和127(含)之间的int或短数字,则让r1和r2为p的任意两次拳击转换的结果。始终是r1 == r2的情况。

答案 1 :(得分:2)

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

JLS指定了装箱行为,正如在评论中指出的那样,这部分是在Integer类中实现的;然而,另一个有趣的注意事项是,即使这个池的大小也可以通过VM参数进行调整。来自Integer.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        */

答案 2 :(得分:1)

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

  

被装箱的值p为真,假,字节或范围为\ u0000到\ u007f的字符,或者介于-128和127(含)之间的int或短数,然后让r1和r2为p的任意两次拳击转换的结果。始终是r1 == r2。

的情况

但总的来说,依赖于此将是愚蠢的,因为您首先必须检查数字是否在缓存范围内,然后有条件地使用==或equals()。 使用==表示原始类型,Class和enum,等于其他一切。