我试图了解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
的区别,后者是首选。
答案 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这个深奥的主题。纯粹是猜测会发生什么。
但绝对令人困惑,这是一个有趣的问题。