字符串 s = 新字符串(“xyz").这行代码执行后生成了多少个对象?

2022-01-16 00:00:00 jvm java

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

The commonly agreed answer to this interview question is that two objects are created by the code. But I don't think so; I wrote some code to confirm.

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());
    }
}

输出是:

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

Does this mean that only one object was created?

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

Reaffirm: My question is how many object was created by the following code:

String s = new String("xyz")

而不是 StringTest 代码.

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

Inspired by @Don Branson, I debugged the below code:

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

结果是:

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

The id of s is 84, and the id of "abc" is 82. What exactly does this mean?

推荐答案

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

首先,这个问题真的问到这里解决的问题:String Literal Pool 是对字符串对象的引用的集合,还是对象的集合

所以,这对每个人来说都是一个指南.

So, that is a guide for everyone on this matter.

...

有两种看待这个的方式:

There are two ways of looking at this:

(1) 代码行执行时会发生什么——它在程序中运行的实际时刻?

(1) What happens when the line of code executes -- the literal moment it runs in the program?

(2) 语句创建了多少Objects 的净效应是什么?

(2) What is the net effect of how many Objects are created by the statement?

a) "xyz" String 在 JVM 加载包含这行代码的 class 时创建和实习.

a) The "xyz" String is created and interned when the JVM loads the class that this line of code is contained in.

  • 如果 "xyz" 已经在其他代码的实习池中,则文字可能不会产生新的 String 对象.
  • If an "xyz" is already in the intern pool from some other code, then the literal might produce no new String object.

b) 当创建新的 String s 时,内部 char[] 是 interned"xyz" 字符串的副本.

b) When new String s is created, the internal char[] is a copy of the interned"xyz" string.

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

c) That means, when the line executes, there is only one additional object created.

事实上,"xyz" 对象将在类加载后并且在此代码部分运行之前创建.

The fact is the "xyz" object will have been created as soon as the class loaded and before this code section was ever run.

...下一个场景...

...next scenario ...

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

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

a) s1 and s2 are just referenced,not objects, and they point to the same String in memory.

b) "a" 是 intern 并且是一个复合对象:一个 char[] 对象和 String 对象本身.它由内存中的两个对象组成.

b) The "a" is interned and is a compound object: one char[] object and the String object itself. It consisting of two objects in memory.

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

c) s3, new String("a") produces one more object. The new String("a") does not copy the char[] of "a", it only references it internally. Here is the method signature:

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

一个实习String ("a") 等于2 个Objects.一个 new String("a") 等于一个对象.代码的净效果是三个对象.

One interned String ("a") equals 2 Objects. And one new String("a") equals one more object. Net effect from code is three objects.

相关文章