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中包装器类的行为[重复]的主要内容,如果未能解决你的问题,请参考以下文章