0

我在 Kathy Sierra 的书中读到,当我们使用像 String s = new String("abc") 这样的 new 运算符创建字符串时,由于我们使用了 new 关键字,Java 将在普通(非池)内存中创建一个新的 String 对象,和 s 将引用它。此外,文字“abc”将被放置在池中。

intern() 表示如果 String 池已经包含一个字符串,则返回池中的字符串,否则,将 String 对象添加到池中并返回对该 String 对象的引用。

如果使用 new 创建的字符串“abc”也将字符串放入池中,那么 intern() 表示如果字符串池包含字符串,则返回池中的字符串,否则将字符串对象添加到池中。

另外我想知道我们是否使用 new 创建了一个字符串,那么实际上创建了多少个对象?

4

2 回答 2

6

TL;DR:如果你真的需要这样做new String("abc"),你就会知道你需要这样做,并且你会知道为什么。它是如此罕见,以至于说你永远不需要这样做几乎是有效的。只需使用"abc".


长版:

当您拥有代码new String("abc")时,会在不同时间发生以下事情:

  • 加载包含该代码的类时,如果带有字符的字符串"abc"不在实习池中,则会创建并放入实习池。
  • new String("abc")代码运行时 :
    • 来自实习生池的字符串的引用"abc"被传递到String构造函数中。
    • 通过将传入的字符复制到构造函数中来创建和初始化一个新对象。 StringString
    • String对象将返回给您。

如果使用 new 创建的字符串“abc”也将字符串放入池中,那么为什么intern()说如果字符串池包含字符串,则返回池中的字符串,否则将字符串对象添加到池中。

因为这就是这样intern做的。请注意,调用intern字符串文字是无操作的;字符串文字都是自动实习的。例如:

String s1 = "abc";               // Get a reference to the string defined by the literal
String s2 = s1.intern();         // No-op
System.out.println(s1 == s2);    // "true"
System.out.println(s1 == "abc"); // "true", all literals are interned automatically

另外我想知道我们是否使用 new 创建了一个字符串,那么实际上创建了多少个对象?

您创建至少一个String对象(新的、非实习的),可能还有两个(如果字面量尚未在池中;但同样,当类文件的字面量被加载时,该位更早发生):

String s1 = "abc";            // Get a reference to the string defined by the literal
String s2 = new String(s1);   // Create a new `String` object (guaranteed)
System.out.println(s1 == s2); // "false"
String s3 = s2.intern();      // Get the interned version of the string with these characters
System.out.println(s1 == s3); // "true"
于 2012-05-13T10:57:44.837 回答
0

字符串池是一个字符串引用池。对象仅在堆中创建。

当使用new String("abc").intern()或使用类似的方法时String s = "abc";如果存在引用“abc”的引用,则检查字符串池。

如果“abc”的引用已经存在于池中,并且.intern()在引用String object创建的 using的引用上被调用new String("abc"),则由创建的对象new String("abc")有资格进行垃圾回收。请参阅下面的代码以获得更清晰的信息。

public static void main(String[] args) {
    String s = new String("abc");
    String a = s;
    System.out.println(s==a);// true
    String b = "abc";
    s = s.intern();
    System.out.println(s==a);// false
} 
于 2016-06-13T16:43:00.233 回答