[[Hay algunas buenas respuestas aquí, pero me parece que todavía se carece de un bit de información. ]]
return (new StringBuilder("select id1, " + " id2 " + " from " + " table"))
.toString();
Como usted señala, el ejemplo que da es simplista, pero analicémoslo de todos modos. Lo que sucede aquí es el compilador que realmente hace el trabajo +
aquí porque "select id1, " + " id2 " + " from " + " table"
son todas constantes. Por lo que este se convierte en:
return new StringBuilder("select id1, id2 from table").toString();
En este caso, obviamente, no hay ningún punto en el uso StringBuilder
.Es lo mismo que hacer:
// the compiler combines these constant strings
return "select id1, " + " id2 " + " from " + " table";
Sin embargo, incluso si se añade los campos u otros no constantes entonces el compilador utilizaría un internaStringBuilder
- no hay necesidad de definir una:
// an internal StringBuilder is used here
return "select id1, " + fieldName + " from " + tableName;
Debajo de las sábanas, esto se convierte en código que es aproximadamente equivalente a:
StringBuilder sb = new StringBuilder("select id1, ");
sb.append(fieldName).append(" from ").append(tableName);
return sb.toString();
realmente la única vez necesita usar StringBuilder
directamente es cuando tiene el código condicional. Por ejemplo, el código que se parece a la siguiente es desesperada de un StringBuilder
:
// 1 StringBuilder used in this line
String query = "select id1, " + fieldName + " from " + tableName;
if (where != null) {
// another StringBuilder used here
query += ' ' + where;
}
El +
en la primera línea utiliza una instancia StringBuilder
. Luego, el +=
usa otra instancia StringBuilder
. Es más eficiente que hacer:
// 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();
Otra vez que utilizo una StringBuilder
es cuando estoy construyendo una cadena de una serie de llamadas a métodos. Entonces puedo crear métodos que toman un argumento StringBuilder
:
private void addWhere(StringBuilder sb) {
if (where != null) {
sb.append(' ').append(where);
}
}
Cuando está utilizando un StringBuilder
, debe ver para cualquier uso de +
al mismo tiempo:
sb.append("select " + fieldName);
Eso +
hará que otra StringBuilder
interno para ser creado. Esto debe ser, por supuesto:
sb.append("select ").append(fieldName);
Por último, como @ T.J.rowder señala, siempre se debe hacer una conjetura en el tamaño de la StringBuilder
. Esto ahorrará en el número de objetos char[]
creados al aumentar el tamaño del búfer interno.
Explique por qué no se logra eso para ayudarlo a comprender eso. :) – Thomas
No crea una instancia separada de 'StringBuilder' para cada concatenación; crea una para toda la expresión. Entonces '" select id1, "+ id2 +" de "+ table" solo crearía un solo 'StringBuilder', y sería significativamente más fácil de leer la IMO. Pruébalo y descompila el código para ver ... –
@JonSkeet: Gracias, estaba pensando en el caso de la expresión múltiple, no en el caso de la expresión única. Fijo. Apreciar la nota. –