当前位置: 首页 > 知识库问答 >
问题:

字符串与实习生比较

季骏祥
2023-03-14

我试图理解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的区别,后者是首选。

共有3个答案

司徒池暝
2023-03-14

这很简单。。。在表面上。

如果你会写:

s2 = s2.intern();

那么位置是不相关的,总是产生s2==s4。

没有赋值的情况下发生的事情似乎是检索s2的奇迹。JVM在引擎盖下交换s2字符串。(使用javap-c进行反汇编并没有显示出什么特别的东西。)

由于intern是本地的,速度很慢,而且涉及到JVM,所以我不愿意进一步深入研究字符串interning这个深奥的主题;纯粹的猜测可能会发生什么。

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

施玉宸
2023-03-14

简单地说,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的内容相同

赵刚豪
2023-03-14

一串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。为什么会这样?