O operador “+” é compilado de várias maneiras pelo Javac.
- Se ambos os operandos forem constantes strings, ele efetua a concatenação em tempo de compilação:
String s = "abc" + "def";
é compilado para algo semelhante a:
String s = __referência à string "abcdef" que está no pool de strings constantes___;
- Se você tiver uma sequência de vários operandos, todos strings, ele normalmente cria um StringBuilder no começo, e usa o método StringBuilder.toString() no fim:
String a = ...;
String b = ...;
String c = ...;
String s = a + b + c;
equivale a:
String s = new StringBuilder (a).append (b).append (c).toString();
- Se você tiver uma sequência de vários operandos, sendo que alguns deles são strings e outros não, ele normalmente cria um StringBuilder no começo, e usa o método StringBuilder.toString() no fim, e chama os overloads de StringBuilder.append que fazem conversão de dados:
String a = ...;
int b = ...;
Object c = ...;
String s = a + b + c;
equivale a:
String s = new StringBuilder (a).append (b).append (c).toString();
- Por que é que, mesmo o compilador criando uma StringBuilder o seguinte código abaixo é péssimo?
String[] t = "abc,def,ghi,asjk,sdlkd,fklklfkfk,jjajjaj";
String s = "";
for (String q : t.split(",")) {
s = s + q; // você deve se lembrar que isso é compilado para "s = new StringBuilder(s).append(q).toString();"
}
É que para cada vez que você executa o loop, são criados 4 objetos:
- Uma StringBuilder, que contém como valor inicial os caracteres de s. Essa StringBuilder contém um char[] que é uma cópia dos caracteres de s
- Talvez seja realocado o char[] contido no StringBuilder se q for grande. Isso já dá o terceiro objeto
- E depois toString() cria um quarto objeto, que é uma String.
Se você fizesse, em vez disso:
StringBuilder sb = new StringBuilder();
for (String q : t.split(",")) {
sb.append (q); // isto deve no máximo criar um novo char[], não 4 objetos a cada iteração do loop.
}
String s = sb.toString(); // só cria o String no final
iria economizar várias criações e cópias de objetos e arrays.
[/code]