Recentemente, quando eu estava procurando um emprego, o examinador me fez uma pergunta simples: "A diferença entre StringBuffer e StringBuilder, quais são seus cenários de aplicação?" A resposta do editor é compartilhada com você abaixo, para que possa ser conveniente para que todos aprendam no futuro, para fazer um registro.
De fato, procure o Google Master e você terá a resposta: StringBuffer é completamente equivalente aos métodos e funções no StringBuilder, mas a maioria dos métodos no StringBuffer usa a palavra-chave sincronizada para modificação, para que sejam seguros de threads. Sem essa modificação, o StringBuilder pode ser considerado thread-insafe.
Para entender melhor a resposta acima, é melhor ver diretamente que a implementação do código -fonte do StringBuffer e StringBuilder é mais realista. Como programador, "Se você tiver alguma dúvida, veja o código -fonte" é o caminho certo. Posso dizer com responsabilidade, é claro, você precisa ter condições!
Na implementação do JDK, o StringBuffer e o StringBuilder são herdados do AbstractStringBuilder. Para a segurança e a não segurança multi-threading, você terá um entendimento aproximado dos métodos sincronizados no StringBuffer.
Aqui, falarei brevemente sobre o princípio da implementação do AbstractStringBuilder: Sabemos que o uso do StringBuffer nada mais é do que melhorar a eficiência da conexão da String em Java, porque se você usar + diretamente para a conexão da String, a JVM criará vários objetos de string, o que causará determinadas sobrecargas. AbstractStringBuilder usa uma matriz de char para salvar a string que precisa ser anexada. A matriz CHAR tem um tamanho inicial. Quando o comprimento da string da string de apêndice excede a capacidade atual da matriz de char, a matriz CHAR é expandida dinamicamente, ou seja, reaplicando um espaço de memória maior e, em seguida, copiando a matriz de char atual para um novo local. Como a sobrecarga de re-alocar memória e cópia é relativamente grande, cada vez que você reaplicando o espaço de memória é da maneira como o espaço de memória é maior que a corrente necessária, que é 2 vezes.
Em seguida, divirta -se!
Aqui estão algumas informações no Google:
【
StringBuffer começou com o JDK 1.0
StringBuilder começou com o JDK 1.5
A partir do JDK 1.5, a operação de conexão (+) com variáveis de string é usada internamente pela JVM
StringBuilder é implementado e essa operação foi implementada usando o StringBuffer.
】
Observamos o processo de execução por meio de um programa simples:
Listagem 1 buffer.java
public class Buffer {public static void main (string [] args) {string s1 = "aaaaa"; String s2 = "bbbbbb"; String r = null; int i = 3694; r = s1 + i + s2; for (int j = 0; i <10; j ++) {r+= "23124"; }}}Use o buffer de comando javap -c para visualizar sua implementação de bytecode:
Listagem 2 classe buffer bytecode
Lista 1 e Lista correspondentes 2, a instrução LDC na lista 2 carrega a string "AAAA" do pool constante para a parte superior da pilha e as lojas IStore_1 "AAAAA" na variável 1. O seguinte é o mesmo. Sipush empurra um valor constante inteiro curto (-32768 ~ 32767) para o topo da pilha. Aqui está a constante "3694". Para obter mais conjuntos de instruções Java, verifique outro artigo "Java Instrutive Sett".
Vamos ver diretamente que 13, 13 ~ 17 é novo em um objeto StringBuffer e chamamos seu método de inicialização. 20 ~ 21 é primeiro a variável de imprensa 1 na parte superior da pilha através do ALOAD_1. Como mencionado anteriormente, a variável 1 é colocada na constante de strings "aaaaaa" e, em seguida, chama o método Apênd de StringBuffer através da instrução InvokeVirtual para unir "AAAAA" juntos. Os 24 ~ 30 seguintes são os mesmos. Finalmente, em 33, a função de tostragem do StringBuffer é chamada para obter o resultado da string e armazenada na variável 3 através da loja.
Quando vemos isso, alguém pode dizer: "Como a JVM usa StringBuffer para conectar strings, não precisamos usar o StringBuffer, basta usar"+"Just!" Isso é verdade? Claro que não. Como diz o ditado, "existe uma razão para a existência", vamos continuar olhando para o bytecode correspondente ao loop subsequente.
37 ~ 42 são todos alguns preparativos antes de entrar no loop for. 37, 38 Defina J a 1. 44 Aqui, o IF_ICMPGE compara j com 10. Se J for maior que 10, ele saltará diretamente para 73, ou seja, a instrução Return sai da função; Caso contrário, ele entra no loop, isto é, o código de byte de 47 ~ 66. Aqui, precisamos apenas olhar para 47 a 51 para saber por que usamos o StringBuffer em nosso código para lidar com conexões de string, porque toda vez que executamos a operação "+", a JVM precisa de novo objeto StringBuffer para lidar com conexões de string, que serão muito caras quando muitas operações de conexão de string estiverem envolvidas.