String s = new String(“xyz”)。执行此行代码后生成了多少个对象?给定这行代码:String s = new String(“xyz”) 答:

2022-09-01 10:54:06

这个面试问题的普遍同意的答案是,代码创建了两个对象。但我不这么认为。我写了一些代码来确认。

public class StringTest {
    public static void main(String[] args) {
        String s1 = "a";
        String s2 = "a";
        String s3 = new String("a");
        System.out.println("s1: "+s1.hashCode());
        System.out.println("s2: "+s2.hashCode());
        System.out.println("s3: "+s3.hashCode());
    }
}

输出为:

Application output

这是否意味着只创建了一个对象?

重申:我的问题是以下代码创建了多少个对象:

String s = new String("xyz")

而不是代码。StringTest

受@Don Branson的启发,我调试了以下代码:

public class test {
    public static void main(String[] args) {
        String s = new String("abc");
    }
}

结果是:

Enter image description here

s 的 id 是 84,“abc” 的 id 是 82。这到底是什么意思?


答案 1

下面有一些错误,具体取决于您使用的 JVM/JRE。无论如何,最好不要担心这样的事情。有关任何更正/疑虑,请参阅评论部分。

首先,这个问题确实询问了这里解决的问题:字符串文本池是对字符串对象的引用集合,还是对象的集合

因此,这是每个人在这个问题上的指南。

...

给定这行代码:String s = new String(“xyz”)

有两种方式来看待这个问题:

(1)当代码行执行时会发生什么 - 它在程序中运行的字面时刻?

(2)语句产生的净效应是多少?Objects

答:

1) 执行此命令后,将创建一个附加对象。

a) 当 JVM 加载包含此行代码时,将创建并暂存。"xyz"Stringclass

  • 如果 某个其他代码已在实习生池中,则文本可能不会生成任何新对象。"xyz"String

b) 创建新字符串时,内部是滞留字符串的副本。String schar[]"xyz"

c)这意味着,当行执行时,只创建了一个额外的对象。

事实是,该对象将在类加载后立即创建,并且在此代码段运行之前。"xyz"

...下一个场景...

2)代码创建了三个对象(包括实习生"a")

String s1 = "a";
String s2 = "a";
String s3 = new String("a");

a)s1和s2只是引用的,而不是对象,它们在内存中指向相同的对象。String

b)“a”是内在的,是一个复合对象:一个对象和对象本身。它由内存中的两个对象组成。char[]String

c) s3,再生成一个对象。新的不复制“a”,它只在内部引用它。下面是方法签名:new String("a")String("a")char[]

public String2(String original) {
        this.value = original.value;
        this.hash = original.hash;
}

一个被拘留者等于2个。一个等于另一个对象。代码的净效果是三个对象。String("a")Objectsnew String("a")


答案 2

将为此创建两个对象:

String s = new String("abc");

一个在堆中,另一个在“字符串常量池”(SCP) 中。引用将指向始终,并且不允许在 SCP 区域中使用 GC,因此 SCP 上的所有对象都将在 JVM 关闭时自动销毁。ss

例如:

在这里,通过使用堆对象引用,我们通过调用intern()来获得相应的SCP对象引用。

String s1 = new String("abc");
String s2 = s1.intern(); // SCP object reference
System.out.println(s1==s2); // false
String s3 = "abc";
System.out.println(s2==s3); //True s3 reference to SCP object here

推荐