[[Existem algumas respostas boas aqui, mas acho que ainda faltam um pouco de informação. ]]
return (new StringBuilder("select id1, " + " id2 " + " from " + " table"))
.toString();
Como você indicou, o exemplo que você deu é simplista, mas vamos analisá-lo de qualquer maneira. O que acontece aqui é que o compilador realmente faz o +
trabalho aqui porque "select id1, " + " id2 " + " from " + " table"
são todos constantes. Então, isso se transforma em:
return new StringBuilder("select id1, id2 from table").toString();
Nesse caso, obviamente, não adianta usar StringBuilder
. Você também pode fazer:
// the compiler combines these constant strings
return "select id1, " + " id2 " + " from " + " table";
No entanto, mesmo se você estivesse anexando quaisquer campos ou outros não constantes, o compilador usaria um interno StringBuilder
- não há necessidade de você definir um:
// an internal StringBuilder is used here
return "select id1, " + fieldName + " from " + tableName;
Nos bastidores, isso se transforma em código que é aproximadamente equivalente a:
StringBuilder sb = new StringBuilder("select id1, ");
sb.append(fieldName).append(" from ").append(tableName);
return sb.toString();
Realmente, a única vez que você precisa usar StringBuilder
diretamente é quando você tem código condicional. Por exemplo, o código que se parece com o seguinte está desesperado por um StringBuilder
:
// 1 StringBuilder used in this line
String query = "select id1, " + fieldName + " from " + tableName;
if (where != null) {
// another StringBuilder used here
query += ' ' + where;
}
O +
na primeira linha usa uma StringBuilder
instância. Então o +=
usa outroStringBuilder
instância. É mais eficiente fazer:
// choose a good starting size to lower chances of reallocation
StringBuilder sb = new StringBuilder(64);
sb.append("select id1, ").append(fieldName).append(" from ").append(tableName);
// conditional code
if (where != null) {
sb.append(' ').append(where);
}
return sb.toString();
Outra vez que uso um StringBuilder
é quando estou construindo uma string a partir de várias chamadas de método. Então, posso criar métodos que recebam um StringBuilder
argumento:
private void addWhere(StringBuilder sb) {
if (where != null) {
sb.append(' ').append(where);
}
}
Quando estiver usando um StringBuilder
, você deve observar se há uso de +
ao mesmo tempo:
sb.append("select " + fieldName);
Isso +
vai causar outro internoStringBuilder
seja criado. Claro que deveria ser:
sb.append("select ").append(fieldName);
Por fim, como @TJrowder aponta, você sempre deve tentar adivinhar o tamanho do StringBuilder
. Isso economizará no número de char[]
objetos criados ao aumentar o tamanho do buffer interno.
PreparedStatement
ou algo semelhante: docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html