0

我遇到了一个非常奇怪的行为,后来发现它是 java 规范的一部分。让我把上述帖子中的相关代码

 Integer a = 1000, b = 1000;
        System.out.println(a == b); //Prints false 

        Integer c = 100, d = 100;
        System.out.println(c == d); //Prints true

这与字符串文字池非常相似,但有一个例外,它有一个限制。让我再次引用 Jon Skeet 对前面提到的帖子的回复。

如果被装箱的值 p 是真、假、一个字节、一个在 \u0000 到 \u007f 范围内的字符,或者一个介于 -128 和 127 之间的 int 或短数字,则令 r1 和 r2 为任意两次装箱转换的结果p。r1 == r2 总是如此。

现在我的问题是,既然我们对字符串文字池没有限制,为什么其他类型不一样?没有这个的设计/性能考虑是什么?有什么办法可以配置吗?

4

2 回答 2

0

既然我们对字符串文字池没有限制,为什么其他类型不一样呢?

因为一组 Java 类中字符串文字的数量是有限的,而且可能相当低。相反,动态装箱的 Integer 实例的数量是没有限制的(嗯,有 2^32 个可能的值)。将它们全部缓存会消耗千兆字节的内存,并且会适得其反。

我什至不是在谈论所有其他类型:char、short、long 等。

这个简单的程序会导致 OutOfMemoryError:

for (int i = 0; i < Integer.MAX_VALUE; i++) {
    Integer.valueOf(i);
}
于 2011-12-29T13:52:54.703 回答
0

从统计上讲,小数字比大数字出现的频率要高得多。正数出现的频率高于负数(所有 0 到 n 循环)。128 对我来说有点低,但 1024 可以覆盖我 99.9% 的数字。我在数据库支持的企业系统中工作,因为我从数据库中获取的行数从未超过 1024 行。所以我的列表都没有超过这个大小,并且它们上的循环是使用的大多数数字(如果我完全使用数字)。无论如何,我用 BigDecimal 或 BigInteger 表示的长 ID,只有我使用的其他长数字是用于可序列化接口的 UNID,它是最终的和长的。

我认为大多数开发人员缓存大型 Integer 对象是不值得的。此外,您不应该使用equals方法====除非我处理原语,否则我从不使用。

于 2011-12-29T13:53:23.720 回答