2

来自String 类的实习方法的javaDocs :

当调用 intern 方法时,如果池中已经包含一个等于该 String 对象的字符串,由 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()真的,而以下是的:

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

4 回答 4

2

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

当您使用 8 时,字符串已经在池中(通过在seven.intern()之前运行,因此当您这样做时,eight == eight.intern()您将在等式的左侧获得新创建的eight字符串,而在右侧由池中的 7 创建的字符串, 不一样

于 2016-03-11T05:47:11.443 回答
1

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

故事的寓意..永远不要使用new String()

您受 JVM 的支配,它可以选择是否已经存在“内部化”字符串,或者是否应该被内部化。进一步来说:

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

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

于 2016-03-11T05:42:10.207 回答
0

pczeus 是正确的。更多信息:

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

第六的答案相同。

七是“Hello2”的第一次出现,直到您调用“七==七.实习生()”才被实习。因为它在那一刻被实习,所以 intern() 的返回值为 7。

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

于 2016-03-11T05:47:53.180 回答
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.

于 2016-03-11T06:02:15.787 回答