为什么intern()不能与文字'java'一起使用?

Abh*_*mar 12 java string string-interning

我试过下面的代码:

public class TestIntern {
  public static void main(String[] args) {
   char[] c1={'a','b','h','i'};
   String s1 = new String(c1);
   s1.intern();
   String s2="abhi";
   System.out.println(s1==s2);//true

   char[] c2={'j','a','v','a'};
   String sj1 = new String(c2);
   sj1.intern();
   String sj2="java";
   System.out.println(sj1==sj2);//false

   char[] c3={'J','A','V','A'};
   String tj1 = new String(c3);
   tj1.intern();
   String tj2="JAVA";
   System.out.println(tj1==tj2);//true
  }
}
Run Code Online (Sandbox Code Playgroud)

我尝试了很多不同的文字.

任何人都可以解释为什么intern()不能按字面意思的方式工作"java"?为什么上面的参考比较要评估true,除非文字是"java"

Pet*_*ček 16

当JVM首次遇到该new String(new char[] {'a', 'b', 'h', 'i'})字符串并对其进行调用intern()时,您刚创建的引用将成为规范引用并存储在字符串常量池中.然后"abhi"从常量池中拉出 - 您的规范实例已被重用.

您的问题是文本"java"在程序启动之前存在于常量字符串池中 - JVM只是将其用于某些用途.因此,调用intern()new String(new char[] {'j', 'a', 'v', 'a'})确实实习生您参考.相反,它从常量池返回预先存在的规范值,您很乐意忽略返回值.

您不应忽略返回值,而是使用它.你永远都不知道自JVM启动以来你的"绝对原创"字符串是否一直没有存在于常量池中.无论如何,所有这些都是依赖于实现的,你应该总是使用intern()方法返回的引用,或者永远不要.不要混在他们之间.

  • @MDSayemAhmed因为`new String()`总是创建一个新引用,它永远不会到达常量池.第一个调用是存储在常量池中的调用,其他调用创建不同的对象,这些对象被`intern()`方法忽略.另一方面,据我所知,"java"文字将始终返回相同的对象.呃,那是在规范中吗?老实说,我不确定. (4认同)