我知道String pool是如何工作的。那说:
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
。如果某些字符串被reused
的可能性很小,是否应该鼓励这一点。我看到的问题是在案例1中,即使不再使用该字符串,该字符串也会长时间保留在范围内。
答案 0 :(得分:6)
doSomething2比doSomething1更好。
没有
如果某些字符串被重用的可能性很小,是否应该鼓励这一点。
没有
我看到的问题是在案例1中,即使不再使用该字符串,该字符串也会在延长期内保留。
我认为你误解了这里发生了什么。
字符串"This string ... returns"
是一个字符串文字,当加载包含这些方法的类时,它将被添加到字符串池中一次。
doSomething1()
不会向字符串池添加字符串。相反,它使用已存在于字符串池中的现有字符串(我上面提到的字符串)。
doSomething2()
方法创建了String池中存在的原始String的新副本。你是正确的doSomething2()
创建的副本不在字符串池中。但是,通过首先创建副本,您无法实现任何有用的功能。你最好只使用原始字符串。
最后,应该注意的是,在加载类时创建的字符串池中的String将保留在那里,直到卸载类(如果它被卸载),或者直到应用程序完成。关于这一点你无能为力......你应该做什么。
(情况类似于C或C ++中字符串文字所发生的情况.AC / C ++字符串文字表示为程序初始化常量区域中的字节序列。它将在程序运行期间存在,并且没有什么可以或应该做的尝试回收空间。)
但是为了理解和完整:这是一个大字符串,只能使用一次,如果我可以保持短范围,为什么把它放在池中?
因为JVM没有尝试(并且在一般情况下不能)确定该常量仅将被使用一次。这种分析很难,而且不值得努力。
对于任何合理大小的字符串文字,不太可能在持续时间内在池中产生任何实际差异。如果字符串文字足够大或数量足以使它确实有所不同,那么它们应该替换为从类路径或其他地方的资源读取的字符串。程序员可以进行此调用...而不是JVM。
答案 1 :(得分:0)
当我们使用new()运算符创建字符串时,它是在堆中创建的,而不是添加到字符串池中,而使用文字创建的字符串是在存在于堆的PermGen区域中的字符串池本身中创建的。
String s = new String(" Test");
不会将对象放在String池中,我们需要调用String.intern()方法,该方法用于将它们显式地放入String池中。它只在你将String对象创建为字符串文字时,例如String s =" Test" Java会自动将其放入String池中。
答案 2 :(得分:-2)
对于Java 7,您可以使用新方法来执行此操作。为方便起见,它会将字符串放入池中。
String myString="Hello StackOverflow";
myString.intern();
if(myString=="Hello StackOverflow")
System.out.println("Equal");
else
System.out.println("Not Equal");