【问题标题】:Behavior of Wrapper class in Java [duplicate]Java中包装器类的行为[重复]
【发布时间】:2012-08-31 16:09:18
【问题描述】:

可能重复:
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 中有字符串字面量常量池的概念的方式,在 Java 中的包装类中我们是否也有类似的概念?

【问题讨论】:

    标签: java wrapper


    【解决方案1】:

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

    JLS 指定装箱行为,正如我在 cmets 中指出的那样,这部分在 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        */
    

    【讨论】:

    • Integer 池化对象,而不是 JVM
    • 啊,这很有趣。所以,和字符串不太一样。
    【解决方案2】:

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

    您将在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 总是如此。

    【讨论】:

    • JLS 说 至少 值 -128 到 127 被缓存,而不是 高达 该范围。它甚至在讨论段落中说:“理想情况下,将给定的原始值 p 装箱总是会产生相同的引用。在实践中,使用现有的实现技术可能不可行。......这将允许(但不要求)共享部分或全部这些参考资料。”
    • @yshavit 更改为 between
    【解决方案3】:

    [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 和枚举使用 ==,对其他所有类型使用 equals。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-19
      • 2011-04-04
      • 1970-01-01
      • 2015-01-14
      • 2015-09-05
      相关资源
      最近更新 更多