字符串实习生()行为

String intern() behaviour

来自 String class 的 intern 方法的 javaDocs :

When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.

考虑以下用例:

    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:

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

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

你受 JVM 的摆布,它可以选择 'internalized' 字符串是否已经存在,或者是否应该被内部化。 更具体地说:

To derive a string literal, the Java Virtual Machine examines the sequence of code points given by the CONSTANT_String_info structure.

If the method String.intern has previously been called on an instance of class String containing a sequence of Unicode code points identical to that given by the CONSTANT_String_info structure, then the result of string literal derivation is a reference to that same instance of class String. Otherwise, a new instance of class String is created containing the sequence of Unicode code points given by the CONSTANT_String_info structure; a reference to that class instance is the result of string literal derivation. Finally, the intern method of the new String instance is invoked.

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

当你使用 8 时,字符串已经在池中(在 运行 seven.intern() 之前,因此当你使用 eight == eight.intern() 时,你将在池的左侧equation 新创建的 eight 字符串,右侧是池中 7 创建的字符串,它们不相同

pczeus 是正确的。更多信息:

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

第六个答案相同

7 是 "Hello2" 的第一次出现,直到您调用 'seven == seven.intern()' 才会被保留。因为它在那一刻被实习了,intern() 的 return 值是 7。

8 是 "Hello2" 的另一个新实例。当它被 intern 时,return 值是 7,而不是 8

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

文字“Hello2”将导致在字符串常量池中创建一个对象。 new String 将在堆上创建一个新的 String 对象,并为 literal 复制该对象的内容。

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

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