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

Java的intern()方法在运行时创建的字符串上的行为如何

符俊材
2023-03-14
class Demo
{  
    public static void main(String[] args)  
    {  
        String s1 = new String("ABC");
        String s2 = s1.concat("ABC");
        String s3 = s2.intern();
        System.out.println(s2 == s3); //true

        String s4 = "ABCABC";
        System.out.println(s3 == s4); //true
    }  
}

字符串s2=s1。concat(“ABC”);将在堆区域上创建一个新的字符串对象“ABCABC”。字符串s3=s2。实习生();应在字符串常量池上创建新的字符串对象。

由于这是两个不同的对象,它们的引用不应该相等。但似乎我错过了一些与intern()相关的重要内容。

共有3个答案

卢作人
2023-03-14

在我看来,如果没有字符串,intern方法将字符串添加到字符串常量池中,然后返回字符串引用。

因此,s4=“ABCABC”aready已经存在字符串池

南宫炜
2023-03-14

来自javadoc:

返回字符串对象的规范表示形式。字符串池最初是空的,由类String私有维护。调用中间方法时,如果池中已经包含一个由equals(Object)方法确定等于此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中并返回对此String对象的引用。因此,对于任何两个字符串s和t,s.intern () == t.intern()当且仅当s.equals(t)为真时才为真。所有文字字符串和字符串值常量表达式都被中间化。字符串文字在Java™语言规范的第3.10.5节中定义

因此,您的代码的内部字符串池发展如下:

public static void main(String[] args)  
{
    String s1 = new String("ABC");  
    // "ABC" generate a new string and add it to intern pool.
    // new String("ABC") uses the already present ABC string to generate a new copy that is not present in the pool. 
    // s1 points to that string that is not present in the internal pool
   

    String s2 = s1.concat("ABC"); 
    // "ABC" is already present. s1.concat("ABC") creates a new string ABCABC that is added to the internal pool. s2 point to that string   

    String s3 = s2.intern();         
    // s2.intern() returns a pointer to ABCABC that is already present in the internal pool. s3 points to that string


   System.out.println(s2 == s3);
   // Prints true because ABCABC present in the internal pool is pointed by both s2 and s3.

    String s4 = "ABCABC";
    // ABCABC is already present in the internal pool. s4 points to that string

    System.out.println(s3 == s4);  
    // Prints true because all s2, s3, s4 points to the same instance ABCABC present in the internal pool.
}  
彭允晨
2023-03-14

来自实习生的文档:

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

在调用intern之前,字符串ABCABC实际上已经在字符串池中!根据上面的说法,如果字符串已经在池中,intern只是从池中返回字符串,而不是在池中创建重复的字符串。这与从代码中的文字创建的字符串是相同的实例

“为什么字符串已经在池中?”我听到你问。这是因为字符串第一次出现在源代码中时没有添加到字符串池。编译器收集源代码中的所有字符串文本,并将它们放入类文件中。当程序开始运行时,类文件中的所有字符串都会放入字符串池。

要实际查看预期的行为,不能使用字符串文字“ABCABC”。例如,您可以将其替换为“ABC”。混凝土(“ABC”):

String s4 = "ABC".concat("ABC"); // this creates a new string
 类似资料:
  • 问题内容: 从String类的javaDocs的intern方法中: 调用intern方法时,如果池已经包含等于equals(Object)方法确定的此String对象的字符串,则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。 考虑以下用例: 有人可以解释为什么 是 正确的, 而以下是 错误的 : 问题答案: 七是您第一次使用字符串’hello2’。因此

  • 问题内容: 我有一个很长的查询。我想在中将其分成几行。用做到这一点的一种方法是使用几个句子,然后将它们与一个+运算符连接起来(我知道,这可能不是最有效的方法,但是我并不真正关心此阶段的性能,只是代码的可读性) 。例: 我尝试在Python中做类似的事情,但是没有用,所以我过去常常拆分长字符串。但是,我不确定这是否是唯一/最佳/最佳的方法。看起来很尴尬。实际代码: 问题答案: 你在谈论多行字符串吗?

  • 问题内容: 我看到很多这样的旧代码: 我看不到使用intern()的任何原因,因为在Javadoc中可以看到:“所有文字字符串和字符串值常量表达式都被插入。” 是否有此意图,也许是在该语言的过去版本中? 问题答案: 这是一种确保实际上不是常数的技术。 当Java编译器看到对最终静态基元或String的引用时,它将该常量的实际值插入使用它的类中。如果您随后在定义类中更改常量值,但不重新编译using

  • 本文向大家介绍如何在Python中创建长的多行字符串?,包括了如何在Python中创建长的多行字符串?的使用技巧和注意事项,需要的朋友参考一下 为了创建多行字符串,我们使用三对来代替使用一对单引号/双引号。例如,  这将给出输出:  请注意,您不能使用此符号插入字符串。此符号也用于在Python中定义文档字符串。

  • 问题内容: 我尝试在Android上的Janino上使用这些东西,并得出结论说,它们根本无法在Dalvik VM中运行。 所以我只想问一个简单的问题:在 Android上 ,是否有可能在运行时编译包含代码的字符串以供应用程序使用。如果是这样,是否有让我这样做的库和/或您可以共享一个代码示例来做到这一点? 对于 (一个非常简单的) 示例,如果我有一个包含以下内容的String对象: 作为一根巨大的弦

  • 我在Kathy Sierra的书中读到,当我们使用new操作符创建String时,比如String s=new String(“abc”),因为我们使用了new关键字,Java将在普通(非池)内存中创建一个新的String对象,s将引用它。此外,字面上的“ABC”将被放置在池中。 intern()表示,如果String pool已经包含一个字符串,则返回池中的字符串;否则,将String对象添加到