我知道字符串池是如何工作的。也就是说:
void doSomething1(){
System.out.println("This string is now added to the string pool and will stay there even after this method returns");
}
void doSomething2(){
String msg = new String("This string is now added to the string pool and will stay there even after this method returns");
System.out.println(msg);
}
doSomething2
是否优于 doSomething1
。鉴于某些字符串被重用
的可能性非常低,是否应该鼓励这样做。我看到的问题是在情况 1 中,即使不再使用该字符串,它也会长时间保留在范围内。
最佳答案
Is doSomething2 better than doSomething1.
没有。
Should this be encouraged, given that some Strings have a very low chance of being reused.
没有。
The problem I see is in case 1, the string stays in scope for extended period even when it is not used again.
我认为您误解了这里发生的事情。
字符串 "This string ... returns"
是一个字符串文字,当类包含这些方法时,它被添加到字符串池一次且仅一次已加载。
doSomething1()
不会将字符串添加到字符串池中。相反,它使用字符串池中已有的字符串(我上面提到的字符串)。doSomething2()
方法对存在于字符串池中的原始字符串进行了全新复制。您是正确的,doSomething2()
创建的副本不在字符串池中。但是,您一开始就创建副本并没有获得任何有用的东西。最好只使用原始字符串。
最后需要注意的是,类加载时创建的字符串池中的String会一直留在那里,直到类被卸载(如果被卸载),或者直到应用程序结束。您对此无能为力……您应该对此无能为力。
(这种情况类似于 C 或 C++ 中的字符串文字所发生的情况。C/C++ 字符串文字表示为程序初始化常量区域中的字节序列。它将在程序运行期间一直存在,并且您无法或应该做任何事情来尝试回收空间。)
But for the sake of understanding and completeness: Here is a big string which is only going to be used once and if I can keep it short scoped, why put it in the pool?
因为 JVM 不会尝试(并且在一般情况下不能)确定常量只会被使用一次。这种分析很困难,而且不值得付出努力。
对于任何合理大小的字符串文字,不太可能在持续时间内它在池中产生任何实际差异。如果字符串文字足够大或足够多以至于它确实有所作为,那么它们应该替换为从类路径或其他地方的资源中读取的字符串。由程序员进行此调用...而不是 JVM。
关于java - 字符串范围 : regular heap vs pool,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18139996/