String intern()行为

时间:2016-03-11 05:37:29

标签: java string string-interning

来自String类的实习方法的javaDocs

  

当调用实习方法时,如果池已包含   字符串等于此字符串对象由equals(Object)确定   方法,然后返回池中的字符串。否则,这个   String对象被添加到池中以及对此String的引用   返回对象。

考虑以下用例:

    String first = "Hello";
    String second = "Hello";

    System.out.println(first == second);

    String third = new String("Hello");
    String fourth = new String("Hello");

    System.out.println(third == fourth);

    System.out.println(third == fourth.intern());
    System.out.println(third.intern() == fourth);
    System.out.println(third == fourth);

    System.out.println(third.intern() == fourth.intern());
    System.out.println(third.intern() == first);

    String fifth = new String(new char[]{'H','e','l', 'l', 'o'});
    String sixth = new String(new char[]{'H','e','l', 'l', 'o'});

    System.out.println(fifth == fifth.intern());
    System.out.println(sixth == sixth.intern());

    String seven = new String(new char[]{'H','e','l', 'l', 'o' , '2'});
    String eight = new String(new char[]{'H','e','l', 'l', 'o' , '2'});

    System.out.println(seven == seven.intern());
    System.out.println(eight == eight.intern());

有人可以解释为什么 seven == seven.intern() true ,而以下是 false

  • System.out.println(fifth == fifth.intern());
  • System.out.println(sixth == sixth.intern());
  • System.out.println(eight == eight.intern());

4 个答案:

答案 0 :(得分:2)

七是你第一次使用字符串'hello2'。因此intern所做的是将您的字符串插入池中(并返回它)。因为它等于你的七个。

当您使用8时,字符串已经在池中(之前运行seven.intern(),因此当您执行eight == eight.intern()时,您将获得新创建的等式左侧eight 1}}字符串,右边是由池中七个创建的字符串,它们不是相同的

答案 1 :(得分:1)

因为当您使用new String()语法时,您没有利用字符串池,而是创建一个新的String实例,无论它是否在池中。

故事的道德......永远不要使用new String()

您受JVM的支配,JVM可以选择是否已经存在“内化”字符串,或者应该将其内化。 更具体地说:

  

为了派生字符串文字,Java虚拟机检查CONSTANT_String_info结构给出的代码点序列。

     

如果先前在类String的实例上调用了String.intern方法,该类包含与CONSTANT_String_info结构给出的Unicode代码点序列相同的Unicode代码点序列,则字符串文字派生的结果是对同一个实例的引用class String。   否则,将创建一个类String的新实例,其中包含CONSTANT_String_info结构给出的Unicode代码点序列;对该类实例的引用是字符串文字派生的结果。最后,调用新String实例的intern方法。

答案 2 :(得分:0)

pczeus是正确的。更多信息:

第五个是包含值“Hello”的新字符串(未检查池)。当你intern()它时,返回值是第四个(第一次出现“Hello”被实习),它不等于第五个。

第六个答案相同。

七是第一次出现“Hello2”并且在你调用'seven == seven.intern()'之前它没有被实习。由于它在那一刻被实习,因此intern()的返回值为7。

八是“Hello2”的另一个新实例。当它被实习时,返回值为7,而不是8

答案 3 :(得分:0)

  String seven = new String(new char[]{'H','e','l', 'l', 'o' , '2'});

文字“Hello2”将导致创建字符串常量池中的对象。新String将在堆上创建一个新的String对象,并带有文本对象内容的副本。

你永远不应该像这样创建String对象,因为它不必要且效率低下。当您执行System.out.println(seven == seven.intern());时,它将打印true

现在,当您执行System.out.println(eight == eight.intern());字符串时,字符串池已经存在,因此它将打印false