Classes e mais classes(){
Dicas

Classes e mais classes

Trataremos específicamente das diferenças entre as classes String e StringBuffer. A classe StringBuilder trabalha de forma semelhante a StringBuffer. A classe String é utilizada para cadeias de caracteres que não podem ser mudadas. Ou seja, os objetos do tipo String são read only, imutáveis. Qualquer operação que resulte na alteração dessa string necessitará de um novo objeto. Por outro lado, a classe StringBuffer é utilizada para cadeias de caracteres que podem ser modificadas, daí a referência ao nome buffer.

Consideremos a seguinte concatenação utilizando a classe String:

aspas String str = new String ("Revista ");
str += "printf!!";


Se usássemos a classe StringBuffer para realizar a mesma concatenação, o código seria:

StringBuffer str = new StringBuffer ("Revista ");
str.append("printf!!");

Observando rapidamente, poderíamos pensar que a primeira forma é mais eficiente pois, no segundo exemplo, temos uma chamada de método adicional "append()". Isso nos induz a pensar que a chamada de método é mais custosa que o uso do operador de concatenação "+" que une dois objetos da classe String.

O operador "+" parece inocente e prático, mas essa praticidade pode custar caro. De fato, a concatenação utilizando StringBuffer produz um código mais rápido. Se analisarmos as instruções dos bytecodes gerados veremos que a concatenação utilizando "+" resulta na criação de um objeto temporário do tipo StringBuffer, que chama o método append().

Sim, mesmo utilizando objetos String, criaremos um objeto a mais do tipo StringBuffer! As coisas ficam interessantes aqui. Como isso é possível?

Como dito anteriormente, a classe String é imutável. A concatenação é uma alteração na cadeia original, sendo necessário a criação de outro objeto. Assim, um StringBuffer é usado para realizar a concatenação.

Após a união das strings, feitas no objeto StringBuffer, ocorre a criação de um novo objeto String a partir da chamada de um método toString(). Cada vez que você concatenar algo utilizando o operador "+" uma nova String é criada, o conteúdo antigo é copiado, o conteúdo adicional é concatenado e a String antiga é descartada. Portanto, a criação temporária de um objeto StringBuffer e sua transformação para String são operações caras.

Em contrapartida, se observarmos o código do bytecode gerado quando se utiliza a classe StringBuffer, notamos que também ocorre a chamada do método append() mas sem a necessidade de criar um objeto StringBuffer temporário. O código cria apenas um objeto, StringBuffer, e o converte para String.

Concluindo, a concatenação com StringBuffer é significativamente mais rápida do que concatenação de objetos String. Se a funcionalidade da classe String é desejada, considere usar um StringBuffer para concatenação e depois realizar uma conversão para String.

}