Pyr*_*cal 12 java autoboxing caching integer
Autoboxing相当可怕.虽然我完全理解之间的差异==和.equals我不能不帮助有后续错误的地狱了我:
final List<Integer> foo = Arrays.asList(1, 1000);
final List<Integer> bar = Arrays.asList(1, 1000);
System.out.println(foo.get(0) == bar.get(0));
System.out.println(foo.get(1) == bar.get(1));
Run Code Online (Sandbox Code Playgroud)
那打印
true
false
Run Code Online (Sandbox Code Playgroud)
他们为什么这样做?它与缓存的整数有关,但如果是这样的话,为什么它们不只是缓存程序使用的所有整数?或者为什么JVM始终不会自动拆箱到原始状态?
打印虚假或真假会更好.
编辑
我不同意旧代码的破坏.通过foo.get(0) == bar.get(0)返回true,您已经破坏了代码.
通过在字节代码中将int替换为int(只要从未赋值为null),就不能在编译器级别解决这个问题.
Jon*_*oth 11
-128和127之间的每个整数都由java缓存.据推测,他们这样做是为了获得性能优势.即使他们现在想要回到这个决定,他们也不太可能.如果有人根据这个构建代码,它们的代码会在取出时中断.对于业余爱好编码,这可能并不重要,但对于企业代码,人们会感到不安并且会发生诉讼.
无法缓存所有整数,因为内存影响将是巨大的.
因为JVM无法知道你想要什么.此外,此更改可能很容易破坏未构建用于处理此案例的遗留代码.
如果JVM在调用==时自动取消装箱到原语,这个问题实际上会变得更加混乱.现在您需要记住==始终比较对象引用,除非可以取消装箱对象.这会引起更多奇怪的混淆案例,就像你上面提到的那样.
而不是担心这一点,只需记住这条规则:
除非您打算通过引用比较它们,否则切勿将对象与==进行比较.如果你这样做,我想不出你遇到问题的情况.
你能想象如果每次Integer携带的收费都会有多糟糕的表现吗?也不起作用new Integer.
Java语言(不是JVM问题)不能总是自动取消装箱,因为为1.5之前的Java设计的代码仍然可以工作.