Java 使用new创建字符串对象及其与intern方法的比较

Java 使用new创建字符串对象及其与intern方法的比较,java,string,Java,String,我在Kathy Sierra的书中读到,在本例中,当我们使用诸如String s=new String(“abc”)之类的新操作符创建String时,因为我们使用了new关键字,Java将在普通(非工具)内存中创建一个新的String对象,s将引用它。此外,文字“abc”将放在池中 intern()表示,如果字符串池已包含字符串,则返回池中的字符串;否则,将向池中添加字符串对象,并返回对此字符串对象的引用 如果使用new创建的字符串“abc”也将该字符串放置在池中,则wht does inter

我在Kathy Sierra的书中读到,在本例中,当我们使用诸如String s=new String(“abc”)之类的新操作符创建String时,因为我们使用了new关键字,Java将在普通(非工具)内存中创建一个新的String对象,s将引用它。此外,文字“abc”将放在池中

intern()表示,如果字符串池已包含字符串,则返回池中的字符串;否则,将向池中添加字符串对象,并返回对此字符串对象的引用

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


我还想知道,如果我们使用new创建字符串,那么实际创建了多少个对象?

TL;DR:如果你真的需要做
新字符串(“abc”)
,你会知道你需要做什么,也会知道为什么。很少有人会说你根本不需要这样做。只需使用“abc”


长版本:

当您拥有代码
新字符串(“abc”)
时,以下情况会在不同的时间发生:

  • 加载包含该代码的类时,如果intern池中还没有包含字符“abc”的字符串,则会创建该字符串并将其放入其中
  • 运行
    新字符串(“abc”)
    代码时:
    • 实习生池中对
      “abc”
      字符串的引用被传递到
      字符串
      构造函数中
    • 新的
      String
      对象是通过复制传递到构造函数中的
      String
      中的字符来创建和初始化的
    • 新的
      字符串
      对象将返回给您
如果使用new创建字符串“abc”时也将该字符串放入池中,那么为什么
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
对象(新的非内部对象),可能还创建了两个(如果该文本不在池中;但是,当加载类文件的文本时,该位会发生在前面):


TL;DR:如果你真的需要做
新字符串(“abc”)
,你会知道你需要做什么,也会知道为什么。很少有人会说你根本不需要这样做。只需使用“abc”


长版本:

当您拥有代码
新字符串(“abc”)
时,以下情况会在不同的时间发生:

  • 加载包含该代码的类时,如果intern池中还没有包含字符“abc”的字符串,则会创建该字符串并将其放入其中
  • 运行
    新字符串(“abc”)
    代码时:
    • 实习生池中对
      “abc”
      字符串的引用被传递到
      字符串
      构造函数中
    • 新的
      String
      对象是通过复制传递到构造函数中的
      String
      中的字符来创建和初始化的
    • 新的
      字符串
      对象将返回给您
如果使用new创建字符串“abc”时也将该字符串放入池中,那么为什么
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
对象(新的非内部对象),可能还创建了两个(如果该文本不在池中;但是,当加载类文件的文本时,该位会发生在前面):


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

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

如果池中已经存在对“abc”的引用,并且在引用使用
新字符串(“abc”)
创建的
字符串对象时调用了
.intern()
,则由
新字符串(“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
} 

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

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

如果池中已经存在对“abc”的引用,并且在引用使用
新字符串(“abc”)
创建的
字符串对象时调用了
.intern()
,则由
新字符串(“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
} 

因此,在我们插入新字符串对象之后,使用new?@anand在heap中创建的对象会发生什么情况?@anand:(所有这些都在heap中。)如果你
intern
新字符串对象,那么假设没有其他未完成的引用,它可以进行垃圾收集,就像任何其他不再有突出引用的对象一样<代码>实习生
返回对实习生的引用