String vs StringBuilder - 对象数

时间:2014-02-05 08:58:35

标签: java string stringbuilder

我遇到了两个代码片段,它们创建了一个要进一步执行的查询:

StringBuilder stringBuilder = new StringBuilder(); 
stringBuilder.append("SELECT * FROM EMPLOYEE "); 
stringBuilder.append("WHERE SALARY > ? "); 
stringBuilder.append("GROUP BY DEPT");

String string = "SELECT * FROM EMPLOYEE " +
"WHERE SALARY > ? " +
"GROUP BY DEPT";

根据我的分析,两个片段都创建了4个对象。第一个片段创建一个StringBuilder对象和3个字符串对象,而第二个片段创建4个String对象。我的分析是否正确?

代码段如何比代码段2效率更高?

5 个答案:

答案 0 :(得分:8)

您的第一个分析是正确的,但第二个代码段仅创建一个字符串对象。因为,它是字符串文字的编译时连接。

答案 1 :(得分:5)

不完全......

第一个版本每次执行创建1 StringBuilder个,并且每个JVM启动时创建3 String个常量(创建/ interned)。当您通过String使用该值时,它将在每次执行时创建另一个stringBuilder.toString()对象。

第二个创建1 String常量(每个JVM启动时创建一次/ interned),因为整个连接的值在编译时是已知的。它实际上等同于:

String string = "SELECT * FROM EMPLOYEE WHERE SALARY > ? GROUP BY DEPT";

答案 2 :(得分:3)

StringBuilder示例将创建4个对象。

第二个例子只会创建一个String对象。即使您连接了3个String文字,模型Java编译器也足够聪明,可以检测到您已经连接了静态String文字,因此会将所有这些附加到其中并创建单个String对象。

因此,

String string = "SELECT * FROM EMPLOYEE " +
"WHERE SALARY > ? " +
"GROUP BY DEPT";

相同
String string = "SELECT * FROM EMPLOYEE WHERE SALARY > ? GROUP BY DEPT";

答案 3 :(得分:0)

字符串是不可变的,因此每次进行连接(。运算符)时,都会在内存中创建一个新的String对象。使用StringBuilder,您可以将文本添加到同一个对象中,因此不需要创建新文本。

答案 4 :(得分:0)

第一个代码段创建1个对象。它在编译时连接。

当您连接可变字符串时,StringBuilder具有更好的性能。例如,使用您的示例:

StringBuilder stringBuilder = new StringBuilder(); 
stringBuilder.append("SELECT * FROM EMPLOYEE "); 
if(salary > 0) {
    stringBuilder.append("WHERE SALARY > ? "); 
}
if(group == true) {
    stringBuilder.append("GROUP BY DEPT");
}

String string = "SELECT * FROM EMPLOYEE ";
if(salary > 0) {
    string = string + "WHERE SALARY > ? ";
}
if(group == true) {
    string = = string + "GROUP BY DEPT";
}