下面的一段 Java 代码返回 true
Integer i1=1;
Integer i2=1;
System.out.println(i1==i2);
那么我们在 Java 中拥有字符串字面量常量池概念的方式,在 Java 中的包装类的情况下是否也有类似的概念?
下面的一段 Java 代码返回 true
Integer i1=1;
Integer i2=1;
System.out.println(i1==i2);
那么我们在 Java 中拥有字符串字面量常量池概念的方式,在 Java 中的包装类的情况下是否也有类似的概念?
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() {}
}
也如毒药在下面的回答中所述:
如果被装箱的值 p 是真、假、一个字节或 \u0000 到 \u007f 范围内的一个字符,或者一个介于 -128 和 127(包括)之间的 int 或短数字,则令 r1 和 r2 为p 的任意两个拳击转换。r1 == r2 总是如此。
对象池是 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 */
[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()。对原始类型、类和枚举使用 ==,对其他所有类型使用等于。