我们什么时候应该在字符串文本上使用字符串的terntern方法

2022-08-31 06:26:31

根据 String#intern() 的说法,如果在 String 池中找到 String,则方法应该从 String 池中返回 String,否则将在 String pool 中添加一个新的字符串对象,并返回此 String 的引用。intern

所以我试了一下:

String s1 = "Rakesh";
String s2 = "Rakesh";
String s3 = "Rakesh".intern();

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

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

我本来以为会被打印出来,因为s3是被拘留的,不会被打印出来。但结果是:两行都被打印出来。这意味着,默认情况下,字符串常量是暂存的。但如果是这样,那么我们为什么需要这种方法呢?换句话说,我们什么时候应该使用这种方法?s1 and s3 are sames1 and s2 are sameintern


答案 1

Java 自动筛选字符串文本。这意味着在许多情况下,== 运算符似乎对字符串的工作方式与对 int 或其他基元值的工作方式相同。

由于字符串文本的暂存是自动的,因此该方法将用于构造为intern()new String()

使用您的示例:

String s1 = "Rakesh";
String s2 = "Rakesh";
String s3 = "Rakesh".intern();
String s4 = new String("Rakesh");
String s5 = new String("Rakesh").intern();

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

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

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

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

将返回:

s1 and s2 are same
s1 and s3 are same
s1 and s5 are same

除了 variable 之外的所有情况中,变量是使用运算符显式创建的,并且在其结果上未使用 method,它是返回 JVM 字符串常量池的单个不可变实例。s4newintern

有关更多信息,请参阅 JavaTechniques“字符串平等和实习”。


答案 2

在最近的一个项目中,一些巨大的数据结构是用从数据库读入的数据(因此不是字符串常量/文本)建立的,但有大量的重复。这是一个银行应用程序,像一个适度的集合(可能是100或200)公司的名称这样的东西到处出现。数据结构已经很大了,如果所有这些公司名称都是唯一的对象,它们就会溢出内存。相反,所有数据结构都引用了相同的 100 或 200 String 对象,从而节省了大量空间。

滞留字符串的另一个小优点是,如果所有涉及的字符串都保证被暂存,则可以使用(成功!)来比较字符串。除了更精简的语法外,这也是一种性能增强。正如其他人所指出的那样,这样做会带来引入编程错误的巨大风险,因此这应该仅作为最后的手段。==

缺点是,实习字符串比简单地将其放在堆上需要更多的时间,并且实习字符串的空间可能有限,具体取决于Java实现。当您处理已知合理数量的字符串并具有许多重复项时,最好这样做。