Java中包装器类的行为[重复]

Posted

技术标签:

【中文标题】Java中包装器类的行为[重复]【英文标题】:Behavior of Wrapper class in Java [duplicate] 【发布时间】: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 中的包装类中我们是否也有类似的概念?

【问题讨论】:

【参考方案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。

【讨论】:

以上是关于Java中包装器类的行为[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Java编程设计---继承

使用抽象基类的C ++“调用纯虚拟方法”[重复]

java builder模式用法[重复]

在另一个css中包含一个css类[重复]

每天一种设计模式-- 策略模式

20145235 《Java程序设计》第4周学习总结