[[这里有一些不错的答案,但我发现它们还是缺少一些信息。]]
return (new StringBuilder("select id1, " + " id2 " + " from " + " table"))
.toString();
正如你所指出的,你给出的例子是一种简化的情况,但我们还是来分析一下。这里发生的事情是编译器实际上执行了加号操作+
,因为"select id1, " + " id2 " + " from " + " table"
都是常量。所以这变成了:
return new StringBuilder("select id1, id2 from table").toString();
在这种情况下,显然使用 StringBuilder
是没有意义的。你可以直接这样做:
// the compiler combines these constant strings
return "select id1, " + " id2 " + " from " + " table";
然而,即使您在追加任何字段或其他非常量,编译器也会使用一个内部的 StringBuilder
-- 您不需要定义一个:
// an internal StringBuilder is used here
return "select id1, " + fieldName + " from " + tableName;
在幕后,这将转换为大约等效于以下代码:
StringBuilder sb = new StringBuilder("select id1, ");
sb.append(fieldName).append(" from ").append(tableName);
return sb.toString();
实际上,唯一需要直接使用 StringBuilder
的时间是当您有条件代码时。例如,下面的代码看起来迫切需要一个 StringBuilder
:
// 1 StringBuilder used in this line
String query = "select id1, " + fieldName + " from " + tableName;
if (where != null) {
// another StringBuilder used here
query += ' ' + where;
}
第一行中的+
使用了一个StringBuilder
实例。然后+=
使用了另一个StringBuilder
实例。更有效率的做法是:
StringBuilder sb = new StringBuilder(64);
sb.append("select id1, ").append(fieldName).append(" from ").append(tableName);
if (where != null) {
sb.append(' ').append(where);
}
return sb.toString();
我使用 StringBuilder
的另一个场景是在我需要从多个方法调用中构建字符串的时候。这样,我可以创建接受 StringBuilder
参数的方法:
private void addWhere(StringBuilder sb) {
if (where != null) {
sb.append(' ').append(where);
}
}
使用StringBuilder
时,同时要注意任何+
的使用:
sb.append("select " + fieldName);
那个
+
会导致另一个内部的
StringBuilder
被创建。当然,应该修改为:
sb.append("select ").append(fieldName);
最后,正如 @T.J.rowder 所指出的那样,您应该始终猜测
StringBuilder
的大小。这将减少在扩展内部缓冲区大小时创建的
char[]
对象的数量。
PreparedStatement
或类似的东西:https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html - Christophe Roussy