10

对于程序中的以下语句,将在堆内存和字符串常量池中创建多少个对象?

我需要清楚地创建对象。我读过的许多资料都没有详细说明。当对象被破坏时,我很困惑。

String a="MAM"+"BCD"+"EFG"+"GFE";

将创建多少个对象?

我正在寻找有关对象、方法和类的生命周期以及 JVM 在动态更改和修改它们时如何处理它们的好材料。

4

6 回答 6

20

"MAM"+"BCD"+"EFG"+"GFE"是一个编译时常量表达式,它编译成"MAMBCDEFGGFE"字符串文字。StringJVM 将在加载包含上述代码的类时从该文字创建一个实例,并将其String放入字符串池中。因此String a = "MAM"+"BCD"+"EFG"+"GFE";不会创建任何对象,请参阅 JLS15.18.1. String Concatenation Operator +

String 对象是新创建的(第 12.5 节),除非表达式是编译时常量表达式(第 15.28 节)。

它只是将池中对象的引用分配String给本地 var a

于 2013-08-07T07:16:27.200 回答
6

仅创建一个对象。

string s1 = "java";
string s2 = "ja" + "va";
s.o.p(s1==s2);

该陈述产生真实的。

String s1="java";
string s2 = "ja";
String s3 = s2 +"va";
s.o.p(s1==s3);

该语句产生错误。

所以至少一个明显的应该是永久的,然后'+'运算符生成新的字符串对象(在非常量池中使用new())。所以,你问的问题也不是永久的。这意味着它只创建一个对象。

于 2013-08-07T07:15:25.797 回答
3

只创建一个对象并将其放置在常量池中,除非它已经存在,在这种情况下使用现有对象。编译器将字符串常量连接在一起,如 JLS 3.10.5 和 15.28 中所指定。

长字符串文字总是可以分解成更短的部分,并使用字符串连接运算符 + 写成(可能带括号的)表达式

http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5

于 2013-08-07T07:15:59.573 回答
3

Most answers seem to focus that a) the complete expression is one compile time constant and b) that the line itself does not construct a new object but only a reference to one object.

However noone so far has mentioned, that String itself contains a reference to an internal char[] (which is also in the constant pool).

Summary: There are two objects in the constant pool (String and char[]). The line does neither create nor destroy any object.

And regarding:

I am confused when the object gets destroyed.

No object is destroyed, since stuff in the constant pool will only be destroyed if the class itself would be unloaded. At most you can say, that the reference a will go out of scope eventually.

于 2013-08-07T09:31:27.773 回答
2

由于String a将编译为"MAMBCDEFGGFE".

于 2013-08-07T07:16:32.547 回答
0

在您的示例中说明单个堆对象的答案是正确的。但是,请考虑以下代码:

public class Tester
{
   public String a="MAM";
   public String b ="BCD";
   public String c = "EFG";
   public String d ="GFE";

   public Tester()
   {
      String abcd = a + b + c + d;
   }
}

在此示例中,创建了 7 个字符串。a,b,c 和 d 不会编译成单个常量 - 它们是成员。然后为每个+运算符创建一个字符串 - 从语义上讲,+它是一个串联,但从逻辑上讲,它是在内存中创建一个新字符串。前 2 个运算符字符串会立即被丢弃,现在可以进行垃圾回收,但仍然会发生内存流失。

Technically there in an 8th object. The instance of Tester.

Edit: This has been proved to be nonsense in the comments

于 2013-08-07T08:38:18.687 回答