我知道在 Java 中有两种创建字符串的方法:
String a = "aaa";
String b = new String("bbb");
通过第一种方式,Java肯定会在字符串池中创建一个String对象,并让a
引用它。 (假设“aaa”之前不在池中。)
用第二种方法,会在堆中创建一个对象,但是jvm会不会也在字符串池中创建一个对象?
在这篇文章中 Questions about Java's String pool ,@Jesper 说:
If you do this:
String s = new String("abc");
then there will be one String object in the pool, the one that represents the literal "abc", > and there will be a separate String object, not in the pool, that contains a copy of the > content of the pooled object.
如果是这样,那么每次使用 new String("bbb");
,都会在池中创建一个对象“bbb”,这意味着通过上述任一方式,java 将始终创建池中的字符串对象。那intern()
是干什么用的呢?在文档中 http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#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.
这意味着有些情况下字符串不在池中,这可能吗?哪一个是真的?
最佳答案
如您所知,String
是 Java 编程语言中的不可变对象(immutable对象),这意味着一旦构造就无法更改。因此,JVM 有能力维护一个文字池,这有助于减少内存使用并提高性能。每次使用 String
文字时,JVM 都会检查文字池。如果文字已经可用,则将返回相同的引用。如果文字不可用,将创建一个新的 String 对象并将其添加到文字池中。
当您尝试创建像原始类型或文字/常量这样的 String
时,会应用此理论。
String str = "bbb";
但是当你创建一个新的String对象时
String str = new String("bbb");
上面提到的规则被覆盖并且总是创建一个新实例。
但是 String
类中的 intern
API 可用于从 literal
中选取 String
引用即使您使用 new
运算符创建了一个 String
,也是池。请检查下面给出的示例。尽管 str3
是使用 new
运算符创建的,因为我们使用了 intern
方法 JVM 从 literal
中获取了引用池。
public class StringInternExample {
public static void main(final String args[]) {
final String str = "bbb";
final String str1 = "bbb";
final String str2 = new String("bbb");
final String str3 = new String("bbb").intern();
System.out.println("str == str1 : "+(str == str1));
System.out.println("str == str2 : "+(str == str2));
System.out.println("str == str3 : "+(str == str3));
}
}
以上代码的输出:
str == str1 : true
str == str2 : false
str == str3 : true
你可以看看:Confusion on string immutability
答案来源:http://ourownjava.com/java/java-string-immutability-and-intern-method/
希希尔
关于java - Java 的 String.intern() 的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22473154/