【问题标题】:When a methd returns a String , will it be a literal or a String object?当一个方法返回一个 String 时,它是一个字面量还是一个 String 对象?
【发布时间】:2020-12-04 21:40:56
【问题描述】:

假设一个方法返回一个字符串

String str = methodCall();

methodCall()的返回类型是String。

我们会得到一个字符串字面量,它会在池内存中还是只是一个字符串对象?

【问题讨论】:

  • 这有什么关系?
  • 你的问题是零意义,String Object,文字也是。这与垃圾收集有什么关系?

标签: java memory-management garbage-collection string-pool java-heap


【解决方案1】:

当一个方法返回一个String时,它是一个字面量还是一个String对象?

这个问题是基于一个误解。

在运行时,每个 Java 字符串都表示为java.lang.String 对象。这包括字符串文字。事实上,(通常)不可能区分源自字符串文字的 String 对象和源自其他方式的对象。

所以......基本上......标题中的问题没有意义。


我们会得到一个字符串字面量,它会在池内存中还是只是一个字符串对象?

  1. 这取决于您返回的字符串是如何创建的。

  2. 并非字符串池中的所有对象都源自字符串文字。

  3. 可以通过调用String.intern 将字符串添加到字符串池中。当字符串文字被具体化时,JVM 会自动执行此操作,但在任何其他情况下它不会自动执行此操作。

因此,上述问题的答案将是,如果方法返回的字符串对象以字符串字面量开始,或者某些应用程序代码通过调用 String.intern 将其放在那里,则该方法返回的字符串对象将位于字符串池中。


最后,请注意,字符串池在很大程度上与现代 JVM 上的现代 Java 应用程序无关:

  • 从 Java 7 开始,字符串池不再是单独的堆区域。
  • 从 Java 8 开始,字符串空间优化(去重)由 GC 本身更有效地执行;见https://openjdk.java.net/jeps/192

调用String.intern 始终是一个相当可疑的优化,因为应用程序几乎不可能准确预测字符串对象的生命周期。实习字符串的缺点是 / 是字符串池索引使用内存,并为垃圾收集器做更多的工作。

【讨论】:

  • 考虑到与intern() 相关的成本,它从来都不是一种优化,而只是一种特殊语义的工具。例如,注解的运行时实现必须解析类文件数据,从中构造字符串,然后使用intern() 重新建立注解值的编译时常量语义。值得注意的是,a 字面量是一个 source code 结构。当你有 foo() { return "xyz"; } 时,你有一个使用文字的方法,但是当你有 bar() { return foo(); } 时,它不使用文字,但仍然具有完全相同的、无法区分的结果。
【解决方案2】:

我认为这取决于 methodCall() 字符串。

【讨论】:

    猜你喜欢
    • 2016-04-19
    • 1970-01-01
    • 2022-01-18
    • 2013-08-06
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多