当前位置: 首页 > 面试题库 >

为什么编译器/ JVM不能使自动装箱“正常工作”?

董意蕴
2023-03-14
问题内容

自动装箱相当吓人。虽然我完全理解之间的差异==.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));

那打印

true
false

他们为什么这样做呢?这与缓存的Integer有关,但是如果是这种情况,为什么它们不只是缓存程序使用的所有Integer?或为什么JVM总是不自动取消装箱到原始状态?

打印false false或true true会更好。

编辑

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

通过在字节码中将Integer替换为int,就不能在编译器级别解决此问题(只要永远不将其分配为null)


问题答案:
  • 他们为什么这样做呢?

Java会缓存-128和127之间的每个整数。他们这样做是为了提高性能。即使他们现在想重新决定,他们也不大可能这样做。如果有人以此为基础构建了代码,则将其取出时其代码将中断。对于爱好编码,这也许并不重要,但是对于企业代码,人们会感到不满,并提起诉讼。

  • 他们为什么不只缓存程序使用的所有Integer?

所有的Integer都不能被缓存,因为对内存的影响将是巨大的。

  • 为什么JVM总是不自动取消装箱到原始状态?

因为JVM无法知道您想要什么。同样,此更改可能会轻易破坏未构建为处理这种情况的旧代码。

如果JVM在对==的调用中自动取消对原语的装箱操作,则此问题实际上将变得更加混乱。现在,您需要记住==总是比较对象引用,除非可以将对象拆箱。就像您上面所说的那样,这将导致更多奇怪的混乱情况。

不用太担心这一点,只需记住以下规则即可:

*除非您打算通过引用将它们进行比较,否则 *切勿 将它们与==进行比较。如果这样做,我将无法想到您遇到问题的情况。



 类似资料:
  • 问题内容: 当Java编译器将原语自动包装到包装类时,它在幕后生成什么代码?我想象它调用: 包装器上的valueOf()方法 包装器的构造函数 还有其他魔术吗? 问题答案: 您可以使用该工具亲自查看。编译以下代码: 编译和反汇编: 输出为: 因此,如您所见,自动装箱将调用static方法,而自动拆箱将在给定对象上调用。没什么,真的- 只是语法糖。

  • 我正在使用Java NIO,由于某种原因,我无法获得files.isHidden()来返回正确的布尔值。程序只是检查目录是否隐藏,如果隐藏,则使其可见,如果不隐藏,则使其隐藏。这就是我所拥有的: 它继续返回false并隐藏目录,尽管目录被隐藏。下面的代码使用旧的File类和Path类可以很好地工作。

  • 我一直在用SceneBuilder 9.0.1在IntelliJ上做一个项目。昨天,在NetBeans 8上做了一个小型项目,12之后由于某种原因没有启动新项目。一旦关闭所有内容并打开IntelliJ项目,fxml文档就无法使用SceneBuilder打开。对于这个问题,需要注意以下几点: 我使用的是9.0.1版,尽管v15也有同样的问题, 其中一个fxml文件的示例如下: 请帮助。

  • 问题内容: 当我执行以下操作时, -包含一个元素,它是一个。 -不编译(错误:构造函数未定义) -包含7个元素,它们是对象 这是代码: 问题: 编译器为什么不自动将to 中的元素装箱并创建一个?这是什么原因呢?是我的愚蠢还是其他原因? 问题答案: 区别在于本身是,而是对对象的引用数组。 方法采用某种类型的变量参数,没有上限。该方法的擦除为。这意味着它将接受从扩展的任何类型的可变数量的参数。 由于不

  • 我有一个简单的测试设置,如 但当我尝试编译测试时,我会遇到53个错误,比如 实际上并没有传达任何关于问题所在的有用信息。我只能假设在我的构建中没有正确配置某些内容。sbt文件或其他地方。 这段代码确实曾经工作过,在我清理东西的过程中,事情发生了变化,现在它被破坏了,没有好的诊断。 有人能提出要找的东西吗?

  • 我正在尝试制作一个简单的Pygame应用程序,其中一些颜色与它们下面的颜色混合。以下是我的代码: 代码列表1: 代码应该使黄色矩形与橙色矩形混合,蓝色矩形与绿色矩形混合。相反,我从中得到了一些东西: 对此: 正如你所看到的,黄色和蓝色矩形不仅与红色矩形(屏幕表面)相融合,而且还为橙色和绿色矩形开了一个洞,这样我们就可以通过它们看到红色矩形。