与实习生的字符串比较

时间:2019-03-01 07:10:08

标签: java

我试图了解String#intern方法。现在,它引起了更多的混乱。

package com;

public class Main {  
public static void main(String[] args) {  

        String s1 = new String("GFG"); // Line-1  
        String s2 = s1.concat("GFG"); // Line-2  
        s2.intern(); // Line-3
        String s4 = "GFGGFG"; // Line-4
//      s2.intern(); // Line -5
        System.out.println(s2 == s4);
  }
}

上面的代码显示为true。如果我在第3行添加注释,而在第5行取消注释,则打印为false。
对于第3行,将检查SCP,并将字符串添加到SCP。 但是在那种情况下s2等于s4呢?
s2仍引用堆中指向SCP常量的对象。是吗?

任何人都可以解释发生了什么吗?我经历了不同的SO问题,但仍然无法理解。

编辑
我只是想了解实习方法。我知道b / w ==equals的区别,后者是首选。

3 个答案:

答案 0 :(得分:3)

String.intern()返回字符串对象的规范表示。 最初为空的字符串池由String类私有维护。

调用intern方法时,如果池已经包含等于equals(Object)方法确定的与此String对象相等的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。

对于任何两个字符串s和t,只要且仅当s.equals(t)为true时,s.intern()== t.intern()才为true。

答案 1 :(得分:1)

简单来说,Intern负责在内存(字符串常量池)中精确复制内容。内存将共享所有复制的内容。

通过在几个字符串上应用String.intern()将确保所有具有相同内容的字符串共享相同的内存。例如,如果一个名字“ Amy”出现了100次,则通过实习可以确保实际上只分配了一个“ Amy”。

为了证明这一点,我们可以使用运算符 == (用于比较参考)和等于方法(用于比较内容)。

public class InternExample{  
public static void main(String args[]){  
String s1=new String("hello");  
String s2="hello";  
String s3=s1.intern();//returns string from pool, now it will be same as s2  
System.out.println(s1==s2);//false because reference variables are pointing to different instance  
System.out.println(s2==s3);//true because reference variables are pointing to same instance  
System.out.println(s2.equals(s3));//true because content are same
}}  

输出:

false
true
true

说明:

情况1::s1和s2的内容相同,但指向内存中的引用不同,因为 new String 总是创建新引用,因此为false。

情况2: s3是从s1插入或复制的,并且指向内存中与intern函数相同的引用,只需复制并保留相同的引用即可。

情况3: s2和s3的内容相同

答案 2 :(得分:1)

在表面上非常简单...

如果您会写:

s2 = s2.intern();

然后位置无关紧要,总是产生s2 == s4。

在没有分配的情况下发生的事情似乎是检索s2的奇迹。 JVM在后台交换s2的字符串。 (用javap -c进行反汇编并没有显示出特别之处。)

intern是本机的,速度很慢, 并且涉及到JVM,我不愿意进一步探讨String Interning这个深奥的主题。纯粹是猜测会发生什么。

但绝对令人困惑,这是一个有趣的问题。