String s = new String("xyz").执行这行代码后,有多少个对象被生成?

smi*_*ann 26 java jvm

这个访谈问题的共同商定答案是代码创建了两个对象.但我不这么认为; 我写了一些代码来确认.

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是:

应用输出

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

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

String s = new String("xyz")
Run Code Online (Sandbox Code Playgroud)

而不是StringTest代码.

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

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

结果是:

在此输入图像描述

s的id是84,"abc"的id是82.这究竟是什么意思?

The*_*tor 22

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

首先,这个问题确实在这里解决了这个问题: String Literal Pool是对String对象的引用的集合,还是对象的集合

所以,这是每个人在这个问题上的指南.

...

鉴于这行代码: String s = new String(“xyz”)

有两种方法可以看出这个:

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

(2)Objects声明创造了多少人的净效应是什么?

回答:

1)执行此操作后,将创建一个附加对象.

a)"xyz" String当JVM加载class包含这行代码时,创建并实现.

  • 如果一个"xyz"已经在其他代码的实习池中,则文字可能不会产生新String对象.

b)String s创建new时,internal char[]是interned "xyz"字符串的副本.

c)这意味着,当行执行时,只创建了一个附加对象.

事实是"xyz",一旦加载了类并且在运行此代码段之前,就会创建对象.

......下一个场景......

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

String s1 = "a";
String s2 = "a";
String s3 = new String("a");
Run Code Online (Sandbox Code Playgroud)

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

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

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

public String2(String original) {
        this.value = original.value;
        this.hash = original.hash;
}
Run Code Online (Sandbox Code Playgroud)

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

  • 天啊!每一滴Java都有自己的海洋. (3认同)
  • 这是不正确的。在我检查过的所有 HotSpot 版本中,表示文字(`"abc"`)的 `String` 实例是在第一次使用时创建的,因此假设之前没有人使用过 `"abc"`,它会被创建正好在 `String s = new String("abc");` 行,而不是类加载时间。顺便说一下,内部数组是否共享,取决于 JRE 版本。在 1.7.0_06 之前,数组被复制到 `String(String)` 构造函数中。 (2认同)

use*_*609 8

将为此创建两个对象:

String s = new String("abc");
Run Code Online (Sandbox Code Playgroud)

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

例如:

这里通过使用堆对象引用,我们通过调用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
Run Code Online (Sandbox Code Playgroud)