我试图理解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问题,但仍然无法理解。
EDIT
我只是想了解实习生方法。我知道b/w==
和equals
的区别,后者是首选。
这很简单。。。在表面上。
如果你会写:
s2 = s2.intern();
那么位置是不相关的,总是产生s2==s4。
没有赋值的情况下发生的事情似乎是检索s2的奇迹。JVM在引擎盖下交换s2字符串。(使用javap-c进行反汇编并没有显示出什么特别的东西。)
由于intern是本地的,速度很慢,而且涉及到JVM,所以我不愿意进一步深入研究字符串interning这个深奥的主题;纯粹的猜测可能会发生什么。
但绝对令人困惑,这是一个有趣的问题。
简单地说,Intern负责在内存中精确复制内容(字符串常量池)。将为所有复制的内容共享内存。
通过应用字符串。几个字符串上的intern()将确保具有相同内容的所有字符串共享相同的内存。例如,如果一个名字“Amy”出现100次,那么通过实习,您可以确保实际上只分配了一个“Amy”。
为了证明这一点,我们可以使用运算符==(用于比较引用)和equals方法(用于比较内容)。
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中插入或复制,并指向内存中与实习生函数相同的引用,只需复制并保持相同的引用,这样它就是真的。
案例3:s2和s3的内容相同
一串intern()返回字符串对象的规范表示形式。最初为空的字符串池由类字符串私下维护。
调用intern方法时,如果池中已经包含一个与equals(object)方法确定的字符串对象相等的字符串,则返回池中的字符串。否则,此字符串对象将添加到池中,并返回对此字符串对象的引用。
因此,对于任意两个字符串s和t,当且仅当s.equals(t)为真时,s.intern()==t.intern()为真。
我读了这篇文章,当我们应该在字符串常量上使用字符串的实习生方法时,但仍然不太清楚String==也与intern()进行比较。我有几个例子。有人能帮我更好地理解这一点吗?
来自String类的intern方法的javaDocs: 调用intern方法时,如果池中已经包含一个由equals(Object)方法确定的等于此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中并返回对此String对象的引用。 考虑以下用例: 有人能解释为什么为真而以下为假吗: <代码>系统。出来println(fifth==第五个.intern()) <代码
问题内容: 以下两段代码是否相同? 问题答案: 它们具有相同的 最终结果 ,但它们并不相同(它们将产生不同的字节码;版本实际上经过了这些步骤,生成了新的字符串对象,然后对其进行中间化)。 来自以下两个相关引号: 调用该方法时,如果池中已经包含与该方法确定的对象相等的字符串,则返回池中的字符串。否则,将此对象添加到池中,并返回对该对象的引用。 所有文字字符串和字符串值常量表达式都将被插入。 因此,
问题内容: 为什么Python仅内置字符串?应该可以扩展到可哈希和可比较的类,对吗? 问题答案: 内联事物的目的是能够通过比较它们的内存地址来进行比较。您要确保永远不要创建两个具有相同值的对象(当程序请求创建一个与现有对象具有相同值的第二个对象时,它会收到对先前存在的对象的引用)。这要求你要实习的东西是 不变的 ; 如果一个被拘禁对象的值可以改变,那么按地址比较它们是行不通的。 在Python中,
我最近了解了Java字符串池,有几件事我不太明白。 使用赋值操作符时,如果字符串池中不存在新字符串,则将在字符串池中创建新字符串。 当使用String构造函数时,我明白无论String池的状态如何,都将在堆中、String池之外创建一个新字符串。 我在某处读到过,即使在使用构造函数时,也在使用字符串池。它将把字符串插入到字符串池和堆中。 我没有找到任何关于这方面的进一步信息,但我想知道这是不是真的
上面的代码返回false,但是如果我注释掉第1行和第2行,它返回true。为什么会这样?