计算不同的字符串对象实例

Count Distinct String Object Instances

在以下代码段中创建了多少个不同的 String 对象实例?

String s1 = new String("hello");
String s2 = "GoodBye";
String s3 = s1;

不确定我在这里的所有推理。

通过使用从 String class 创建实例的关键字 new,我猜它必须是一个对象。但是,我很困惑,在 new 之后的 String 现在被认为是一种方法,因为它有 ( ) 然后它在其中调用 String 文字 "hello" 吗?

String s2 = "Goodbye"; 我认为这是一个字符串文字,并且由于字符串实际上是对象,所以即使字符串文字也被视为对象。 不能 100% 确定这是不是真的。

String s3 = s1; 只是指回 s1。因此,它是不明确的。

所以我的答案是 2 个不同的对象。

请说明我说的对不对

正确答案是 3。

String s1 = new String("hello");
String s2 = "GoodBye";
String s3 = s1;

编译器会把文字 "hello""GoodBye" 放入 "constant pool"编译时间,然后将由 classloader 加载。因此,当 JVM 加载 class 时,它会自动保留此 class 使用的所有字符串文字。有关此的更多信息:When are Java Strings interned?. The String constant pool 然后在运行时进行管理。

在运行期间,JVM 将在到达行 String s1 = new String("hello").

时创建第三个 String 对象

所以你会得到三个不同的 String 对象,其中两个包含相同的词 "hello"。所以 s1.equals("hello") 将是 true,但 s1 == "hello" 将是 false,因为 s1 引用堆上的另一个字符串,而不是文字 "hello".

String s3 = s1 只是创建了一个变量 s3,并复制了对 s1 的字符串对象的引用。它不会创建新对象。

另请注意,您可以"manually"使用方法String#intern将字符串添加到字符串常量池中。所以 s1.intern() == "hello"true,因为从 s1.intern() 返回的字符串引用是对已经在常量池。

如果您想通过一些关于物体及其位置的图画获得另一个也许更详细的解释,您可以查看 this article on javaranch