为什么编译器/ JVM不能只进行自动装箱“正常工作”? [英] Why can't the compiler/JVM just make autoboxing "just work"?

查看:74
本文介绍了为什么编译器/ JVM不能只进行自动装箱“正常工作”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Autoboxing相当可怕。虽然我完全理解 == .equals 之间的区别,但我不得不帮助将跟踪错误带到地狱在我之外:

Autoboxing is rather scary. While I fully understand the difference between == and .equals I can't but help have the follow bug the hell out of me:

    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));

打印

true
false

他们为什么这样做?它与缓存的整数有关,但如果是这样的话,为什么它们不只是缓存程序使用的所有整数?或者为什么JVM总是不会自动取消原始设置?

Why did they do it this way? It something to do with cached Integers, but if that is the case why don't they just cache all Integers used by the program? Or why doesn't the JVM always auto unbox to primitive?

打印false false或true true会更好。

Printing false false or true true would have been way better.

编辑

我不同意旧代码的破坏。通过 foo.get(0)== bar.get(0)返回true,你已经破坏了代码。

I disagree about breakage of old code. By having foo.get(0) == bar.get(0) return true you already broke the code.

这不能在编译器级别通过在字节代码中用int替换Integer来解决(只要它从未被赋值为null)

Can't this be solved at the compiler level by replacing Integer with int in byte code (as long as it is never assigned null)

推荐答案


  • 他们为什么这样做?

  • -128到127之间的每个整数由java缓存。据称,他们这样做是为了获得性能优势。即使他们现在想要重新做出这个决定,他们也不太可能。如果有人根据这个构建代码,那么当代码被取出时,它们的代码就会中断。对于业余爱好编码,这可能并不重要,但对于企业代码,人们会感到不安并且会发生诉讼。

    Every Integer between -128 and 127 is cached by java. They did this, supposedly, for the performance benefit. Even if they wanted to go back on this decision now, it's unlikely that they would. If anyone built code depending on this, their code would break when it was taken out. For hobby coding, this perhaps doesn't matter, but for enterprise code, people get upset and lawsuits happen.


    • 为什么不呢?只缓存程序使用的所有整数?

    所有整数都不能被缓存,因为内存的影响是巨大的。

    All Integers cannot be cached, because the memory implications would be enormous.


    • 为什么JVM总是不会自动拆箱到原始状态?

    因为JVM无法知道你想要什么。此外,这种更改很容易破坏未构建的遗留代码来处理这种情况。

    Because the JVM cannot know what you wanted. Also, this change could easily break legacy code not built to handle this case.

    如果JVM在调用==时自动取消装箱到原语,这个问题实际上会变成更混乱。现在您需要记住==始终比较对象引用,除非可以取消装箱对象。这会引起更多奇怪的混淆案例,就像你上面提到的那样。

    If the JVM to automatically unboxed to primitives on calls to ==, this issue will actually become MORE confusing. Now you need to remember that == always compares object references, unless the Objects can be unboxed. This would cause yet more weird confusing cases just like the one you stated above.

    而不是太担心这一点,只需记住这条规则:

    Rather then worry too hard about this, just remember this rule instead:

    从不将对象与==进行比较,除非您打算通过引用对它们进行比较。如果你这样做,我想不出你遇到问题的情况。

    NEVER compare objects with == unless you intend to be comparing them by their references. If you do that, I can't think of a scenario in which you'd run into an issue.

    这篇关于为什么编译器/ JVM不能只进行自动装箱“正常工作”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆