gpt4 book ai didi

java - 为什么在java中,当最终结果是interned对象的不可变副本时,编译器不优化new?

转载 作者:行者123 更新时间:2023-12-02 09:54:14 25 4
gpt4 key购买 nike

我们的行为是,如果使用字符串常量,Java 编译器将使用相同的实例

  String a = "abc";
String b = "abc";
//a == b
String c = new String("abc");
// c is a brand new object on the heap;

为什么 java 编译器不优化新的 String 并用等效的赋值替换它?是有一些深刻的设计决定还是只是巧合?我们是否可以期望不同的 JVM 或编译器更加积极,并且实际上用众所周知的静态对象替换不可变对象(immutable对象)的堆实例?虽然 String 是最臭名昭著的例子,但我们也可以对 Integer 有相同的行为。

最佳答案

首先,String(String)“复制”构造函数源于最初的日子,是一种异常现象。也许是因为 String.intern() 做了一些复制预防,常量 "..." 也是如此。它永远不需要,因为 String 是一个不可变的 final 类。

对于Integer,有Integer.valueOf(int),它使用瞬时缓存,默认情况下保存-128到127。

尽管有非常有能力的编译器开发团队参与,但 java 字节码编译器的编译非常简单。但是,从字节码到机器码,可能会发生一些好事。例如,对象不是在堆上创建的,而是在堆栈上创建的。

简单的编译至少不太可能在智能技巧的数据流分析中包含错误。 (它也为良好的代码风格提供了充分的理由。)

一个例子:

List<String> list = ...
String[] array1 = list.toArray(new String[0]);
String[] array2 = list.toArray(new String[list.size()]);

toArray 需要一个实际的数组实例,因为由于类型删除,List list 不再知道它包含 String

历史上,作为优化,我们可以传递一个适合大小的数组(这里是带有 list.size() 的版本),然后将其返回。更优化、更快,并且仍然有一些风格检查标记第一个版本。然而,实际上第一个版本更快,因为使用了其他数组字节 cdoe 实例化,并且 array1 的生成速度会稍快一些。

关于除以某些数字的相同故事。在 C 语言中,有许多涉及更快转换的编译器优化。这是(部分)在 Java 中通过字节码到机器码编译完成的,这是这些优化的更合乎逻辑的地方。

我个人认为优化字节码编译器会很好,也许适合大学项目。然而,仅仅为了代码改进可能是不合理的,例如不使用 .equals 来表示枚举值。

关于java - 为什么在java中,当最终结果是interned对象的不可变副本时,编译器不优化new?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56112702/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com