String intern()方法使用混乱

时间:2015-02-08 16:31:44

标签: java string

我们对通过新String()创建的Strings使用intern()方法,以便它们在String Pool中创建一个条目并从String Pool返回新创建的String,以便这个创建的字符串可用于==运算符(根据我的理解)。

那么通过构造函数创建新String的用途是什么?

我们什么时候应该使用构造函数来创建新的String?

2 个答案:

答案 0 :(得分:-1)

new String()最多可以创建两个String对象,至少创建一个。一个在常量池中(如果在常量池中不存在),另一个在堆内存中。 常量池条目由interning String对象创建。

intern将在常量池中创建String Literal,这样无论何时创建没有new关键字的String,它都不会创建字符串对象。

假设您已创建为

String str= new String("abc");

将在常量池中创建一个对象(如果常量池中不存在“abc”)。 jvm将在内部调用该对象的实习生。 所以,如果你正在做下一次

String str1= "abc";

不会在常量池中添加任何条目,因为只有相同文字的常量池才能输入。

答案 1 :(得分:-1)

public native String intern(); java doc says, 
  

字符串池(最初为空)由类> {@ code String}私有维护。当调用intern方法时,如果池已经>包含一个等于此{@code String}对象的字符串,由> {@link #equals(Object)}方法确定,那么池中的字符串是> ;回。否则,将此{@code String}对象添加到池中,并返回对此{@code String}对象的引用。因此,对于任何两个字符串{@code s}和{@code t},{@ code s.intern()==> t.intern()}是{@code true}当且仅当{ @code s.equals(t)}是{@code> true}。

让我们考虑一个例子:

String temp1 = new String("abcd");这意味着,将在"abcd"中创建一个新对象heap memory,其引用将链接到temp1

String temp2 = new String("abcd").intern();这意味着将在"abcd"中检查String Pool字面值。如果已存在,则其引用将链接到新创建的temp2。否则,将在String Pool中创建一个新条目,其引用将链接到新创建的temp2

String temp3 = "abcd";这意味着将在"abcd"中检查String Pool字面值。如果已存在,则其引用将链接到新创建的temp2。否则,将在String Pool中创建一个新条目,其引用将链接到新创建的temp3。结论是, Java自动实习字符串文字

让我们考虑另一个例子:

String s1 = "string-test";

String s2 = new String("string-test");

String s3 = new String("string-test").intern();

if ( s1 == s2 ){
    System.out.println("s1 and s2 are same");
}

if ( s2 == s3 ){
    System.out.println("s2 and s3 are same" );
}

if ( s1 == s3 ){
    System.out.println("s1 and s3 are same" );
}

输出:s1 and s3 are same

现在何时使用= " "或使用new String(" ")创建String对象?

我遇到的一个用例,

// imagine a multi-megabyte string here String s = "0123456789012345678901234567890123456789"; String s2 = s.substring(0, 1); s = null;

你现在有一个String s2,虽然它似乎是一个单字符的字符串,但它拥有对String中创建的巨大char数组的引用。这意味着阵列不会被垃圾收集,即使我们已经明确地排除了String!

对此的修复是使用这样的String构造函数:

String s2 = new String(s.substring(0, 1));