gpt4 book ai didi

Java:String intern() 和 StringPool 究竟是如何工作的?

转载 作者:行者123 更新时间:2023-12-03 23:14:08 26 4
gpt4 key购买 nike

根据 Javadoc 关于 String.intern() :

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

我有几个问题。

  1. 当创建一个新的 String 对象(不是使用字符串文字而是使用 new() 运算符)时,如下所示:
    String str = new String("测试");

问题:我知道将在堆中创建一个新对象。但是它是否也会在对象创建期间将 String Test 放入字符串池中?如果是,那么为什么不直接为字符串池返回引用。如果不是,为什么不直接将字符串放入池中,因为现在 StringPool 已移出 PermGen 并位于常规堆空间中(即除了堆空间限制之外没有空间限制)。有一些帖子指出,一旦创建对象,字符串就会被插入池中,而也有一些帖子与此相矛盾。

  1. 一旦我们在 String 对象上调用 String.intern()(因为字面量已经被驻留),分配给该对象的空间会发生什么变化?是同时回收还是等待下一个GC周期?

  2. 已接受对 another question 的回答在 SO 上,指出当您需要速度时应使用 String intern,因为您可以通过引用比较字符串(== 比等于快)。

问题:我知道在使用 String.intern() 时它会返回对 StringPool 中已存在的字符串的引用。但这需要对 StringPool 进行全面扫描查找,这本身​​就是一项昂贵的操作。那么在字符串比较过程中达到这种速度是否合理?如果是,为什么?

我查看了以下来源:

最佳答案

  1. 所有字符串文字都在编译时被保留。使用带有字符串的单个参数构造函数的字符串文字有点滥用该构造函数,因此您可能会得到其中两个(但也许有一个特殊的编译器案例,我不能肯定地说).从 Java 8 开始,构造函数(对于 openjdk)的实现是这样的:
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}

所以这边没有特殊处理。如果您知道文字,请不要使用此构造函数。

  1. 我认为字符串没有任何特殊的 GC 语义。一旦它无法访问并且被 GC 认为与任何其他对象一样值得收集,它就会被收集。

  2. 永远不要使用 == 来比较字符串,字符串的默认 equals 方法的第一步就是这样做。如果这是你的主要情况(你知道你大部分时间都在使用 interned strings)你只需要支付一个很小的方法调用的开销,那么你通过做这样的事情添加的 future 错误的可能性太大了风险微乎其微。

关于Java:String intern() 和 StringPool 究竟是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34474284/

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