以下代码将创建多少个字符串对象?
String s = "Mahendra" + "Singh" + "Dhoni";
它会在字符串池中创建4个字符串对象还是会创建更多?请详细解释。
P.S。我见过其他例子,他们只处理2个字符串对象。
编辑:我从答案中看到,在上面的情况下,只会创建一个对象。非常感谢一些非常好的建议。很抱歉问一个愚蠢的问题,但是你可以在下面的情况下告诉你将创建多少个对象吗?
String s = "Mahendra";
s = s + "Singh" + "Dhoni";
第二次编辑:再次抱歉,但我还有一些疑问。我在评论中看到,在上面的例子中,将创建3个对象" Mahendra"," SinghDhoni"和#34; MahendraSinghDhoni"。 我的疑问不应该从左到右计算。我错过了什么 - 概念明智吗?请帮忙。
另外,在另一种情况下,如果我扭曲这个问题,对象的数量将如何变化。我正在详细询问这一点,以便为很多同事清除它。所有的帮助表示赞赏。
String s = "Singh";
s = "Mahendra" + s + "Dhoni";
答案 0 :(得分:5)
如果你的代码是:
public static void main(String[] args) {
String s = "Mahendra" + "Singh" + "Dhoni";
System.out.println(s);
}
查看字节代码:
public static void main(java.lang.String[]);
descriptor: ([Ljava/lang/String;)V
flags: ACC_PUBLIC, ACC_STATIC
Code:
stack=2, locals=2, args_size=1
0: ldc #16 // String MahendraSinghDhoni --> This line
2: astore_1
3: getstatic #18 // Field java/lang/System.out:Ljav
/io/PrintStream;
6: aload_1
7: invokevirtual #24 // Method java/io/PrintStream.prin
ln:(Ljava/lang/String;)V
10: return
如您所见,编译器在编译期间添加所有三个字符串 。因此 String常量池上只有只有一个字符串。
编辑:根据编辑过的问题:
"Singh" + "Dhoni"
将在编译时期间添加。所以总共会有3个String对象。
"Mahendra"
和"SinghDhoni"
将位于字符串常量池上,然后
mahendraSinghDhoni
将位于堆。
答案 1 :(得分:1)
这将在字符串池中仅创建1个字符串。请阅读差异bwt String对象和文字,它将帮助您理解。
答案 2 :(得分:1)
这是编译器进行优化的特殊条件。 不同的编译器可以进行不同的优化。 以下是可能发生的事情:
编译器查看已知值的字符串连接。如果值未在其他位置使用,则可以使用最终字符串替换串联,因此
String concatenation = "a" + "b" + "c";
编译为
的等效字节代码String concatenation = "abc";
在这种情况下,您只需创建一个字符串。
在一定数量的字符串连接中,编译器可以决定用StringBuilder
或StringBuffer
替换它们。
所以
String a;
String b;
String c;
String d;
String e;
// Initialization and use of a, b, c, d, e
String concat = a + b + c + d + e;
被编译为以下java代码的等效字节码:
String a;
String b;
String c;
String d;
String e;
// Initialization and use of a, b, c, d, e
String concat = new StringBuilder(a).append(b).append(c).append(d).append(e).toString();
在这种情况下,您将创建6个字符串:a,b,c,d,e,以及从+ b + c + d + e获得的字符串
如果StringBuilder的创建不方便,编译器可以应用正常的字符串连接,所以下面的代码
String a;
String b;
String c;
// Initialization and use of a, b, c
String concat = a + b + c;
编译为等效于以下java代码的字节码
String a;
String b;
String c;
// Initialization and use of a, b, c
String concat = a.concat(b).concat(c);
以下是concat代码的java实现:
public String concat(String str) {
int otherLen = str.length();
if (otherLen == 0) {
return this;
}
char buf[] = new char[count + otherLen];
getChars(0, count, buf, 0);
str.getChars(0, otherLen, buf, count);
return new String(0, count + otherLen, buf);
}
正如您在concat的最后一行所看到的,为每个连接创建了一个新的String。在这种情况下,您将创建5个字符串:a,b,c,a + b和a + b + c
注意:任何不同的编译器都可以选择从源代码到编译代码的不同内部优化。您需要知道的是,在最坏的情况下,每个起始字符串将生成1个字符串,每个连接将生成1个字符串(每个+)。因此,如果您有3个字符串与2个连接操作连接,则最多可创建5个字符串。