我遇到了两个代码片段,它们创建了一个要进一步执行的查询:
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效率更高?
答案 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";
}