【问题标题】:Autoboxing rules, what lies under the hood? [duplicate]自动装箱规则,引擎盖下隐藏着什么? [复制]
【发布时间】:2011-12-29 13:36:39
【问题描述】:

我遇到了一个非常奇怪的行为,后来found to be a part of java specs。让我把上述帖子中的相关代码放上去

 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 之间的整数或短数字,然后 设 r1 和 r2 是 p 的任意两次装箱转换的结果。这是 总是 r1 == r2。

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

【问题讨论】:

  • 是的,它自 Java 5.0 (2004) 以来就一直存在,我在这个主题上写的已经足够多了。 ;)
  • 您可以为包装类型提供某种“文字池”,尽管文字实际上是原语。但是为什么要打扰呢?有趣的案例是变量变量。当人们试图用常数值测试东西时,让== 以不同的方式工作可能不会有帮助。

标签: java autoboxing


【解决方案1】:

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

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

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

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

for (int i = 0; i < Integer.MAX_VALUE; i++) {
    Integer.valueOf(i);
}

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      • 1970-01-01
      • 1970-01-01
      • 2010-12-08
      • 2012-12-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多