我遇到了两个代码片段,这些代码片段正在创建一个要进一步执行的查询:
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个字符串对象。我的分析正确吗?
摘要如何比摘要2?
您的第一个分析是正确的,但是第二个摘要仅创建一个字符串对象。因为,这是字符串文字的编译时间串联。
不是完全...
第一个版本创建1个StringBuilder
每个执行和3个String
常数(每JVM启动一次/实施一次)。当您通过stringBuilder.toString()
使用该值时,它将创建另一个String
对象。
第二个创建1 String
常数(每JVM启动一次/实施一次),因为整个串联的值在编译时已知。它等效于:
String string = "SELECT * FROM EMPLOYEE WHERE SALARY > ? GROUP BY DEPT";
StringBuilder
示例将创建4个对象。
第二个示例只会创建一个字符串对象。即使您已经加入了3个String
文字,模型Java编译器也足够聪明,可以检测到您具有conted static String
文字,因此将将所有这些文字都添加到一个中,并创建一个String
对象。
因此,
String string = "SELECT * FROM EMPLOYEE " +
"WHERE SALARY > ? " +
"GROUP BY DEPT";
与
相同String string = "SELECT * FROM EMPLOYEE WHERE SALARY > ? GROUP BY DEPT";
字符串是不可变的,因此每次进行连接时(。操作员)您在内存中创建一个新的字符串对象。使用StringBuilder,您将文本添加到同一对象中,因此不需要创建新对象。
第一个摘要创建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";
}