【问题标题】:Does Java optimize immutable objects?Java 是否优化了不可变对象?
【发布时间】:2013-02-22 09:22:52
【问题描述】:

Java 字符串是不可变的,实例化多个具有相同值的字符串会返回相同的对象指针。 (有这个术语吗?“池化”似乎很合适,但这已经是指通过减少实例化来进行缓存以节省时间。)

Java 是否也对其他(用户定义的)不可变类执行此操作(没有术语的事情)? Java 甚至可以检测到一个类是不可变的,还是字符串类独有的东西?

【问题讨论】:

  • +1 有趣的问题。我相信 Java 可以识别只有最终成员的类并将它们视为不可变的,但我对此没有确切的信息。我会关注这个问题。谢谢
  • 它没有,考虑一下如果你用反射改变了不可变对象会发生什么..
  • 我明白了,我对此有点惊讶。谢谢
  • “这个有术语吗?” Java 称之为"interning" the string。
  • new String("blah") != new String("blah") 所以你的第一句话不太准确。

标签: java optimization immutability


【解决方案1】:

正如这里的其他人所说,这个使用字符串的过程称为实习。

值得一提的是,在 Java 7 中,具有相同字面值的字符串的行为可能是相同的对象,也可能不是。从 7 开始:

在 JDK 7 中,interned 字符串不再分配在 Java 堆的永久代中,而是与其他创建的对象一起分配在 Java 堆的主要部分(称为年轻代和年老代)中由应用程序。此更改将导致更多数据驻留在主 Java 堆中,而永久代中的数据更少,因此可能需要调整堆大小。由于此更改,大多数应用程序只会看到相对较小的堆使用差异,但加载许多类或大量使用 String.intern() 方法的大型应用程序将看到更显着的差异。

查看Java SE 7 RFE 了解有关此内容的完整详细信息。

关于你自己的不可变对象,Java 没有对它们做任何特别的事情——它不知道它们是不可变的。如果它能够检测到它的价值/可能,它可能内联方法多一点,但就编译器和 JVM 而言,它们只是另一个对象。

【讨论】:

  • 哇,被否决了?我可以投反对票,但很高兴知道原因
【解决方案2】:

写。字符串,你要找的词是interning。

Java 不会为您自己的不可变对象执行此操作。不过,它确实有盒装原语的缓存版本。有关更多信息,请参阅wrapper class caching 上的这篇文章。

【讨论】:

    【解决方案3】:

    您正在查找的术语正在迭代。 Java 在编译期间“自动”优化字符串,并为开发人员提供了在运行时执行此操作的可能性。 (具体取决于JVM版本优化的细节。)

    就不可变对象而言。我不认为 Java 支持任何类型的机制来解决相同的实例。字符串类型不是此规则的例外。

    原因是你必须使用操作符new 来创建一个实例。如果你使用new 创建字符串实例,你总是会得到两个不同的对象。

    intering 仅适用于 String 类型。但是这个概念是免费的,你可以将这样的方法添加到你的不可变类中,并编写一个完成同样事情的方法。

    【讨论】:

      【解决方案4】:

      字符串实习。维基百科:String Interning

      【讨论】:

        【解决方案5】:

        String Interning 是 String 类独有的。我想 JVM 不会将这些规则应用于用户定义的类。

        【讨论】:

          猜你喜欢
          • 2014-09-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-04
          • 2023-04-10
          • 1970-01-01
          相关资源
          最近更新 更多