Eu estava ocupado com a implementação lógica do projeto durante a semana. Eu tive algum tempo no sábado, então peguei uma versão grossa em inglês de pensamento em Java da estante e li o emenda de objetos de cordas. Consulte este livro como uma tradução, adicione o que você pensa e escreva este artigo para gravá -lo.
Objeto de string imutável
Em Java, os objetos de string são imutáveis (imutáveis). No código, você pode criar vários alias para um objeto String. Mas as referências desses aliases são iguais.
Por exemplo, S1 e S2 são alias para objetos "droidyue.com", e os alias são armazenados em referências ao objeto real. Então S1 = S2
String s1 = "dRoidyue.com"; string s2 = s1; system.out.println ("s1 e s2 tem a mesma referência =" + (s1 == s2));O único operador sobrecarregado em Java
Em Java, o único operador sobrecarregado está relacionado ao splicing de string. +,+=. Além disso, os designers de Java não permitem a sobrecarga de outros operadores.
Análise de emenda
Existe realmente um custo de desempenho?
Depois de entender os dois pontos acima, você pode ter esses pensamentos. Como o objeto Sting é imutável, a emenda de múltiplas (três ou mais) strings produzirá inevitavelmente objetos de string intermediários desnecessários.
String userName = "Andy"; String AGE = "24"; String Job = "Developer"; String Info = Nome de Usern + Age + Job;
Para obter as informações acima, o nome de usuário e a idade serão unidos para gerar um objeto de string temporário T1, com o conteúdo de Andy24, e então o T1 e os trabalhos serão unidos para gerar o objeto de informações de que precisamos no final. Entre eles, um T1 intermediário é gerado e, após a criação de T1, ele não será reciclado automaticamente, o que inevitavelmente ocupará uma certa quantidade de espaço. Se for um splicing de muita (assumindo centenas, mais comum na sequência de chamadas de toques para o objeto), o custo será maior e o desempenho será muito menor.
Processamento de otimização do compilador
Existe realmente o custo de desempenho acima? O splicing de cordas é tão comum, não há otimização especial de processamento? A resposta é que essa otimização é realizada quando o compilador compila .java para bytecode.
Se um programa Java quiser executar, levará dois períodos, tempo de compilação e tempo de execução. No momento da compilação, o compilador Java (compilador) converte o arquivo java em bytecode. Em tempo de execução, a Java Virtual Machine (JVM) executa o bytecode gerado por tempo de compilação. Durante esses dois períodos, o Java alcançou a chamada compilação e corrida em todos os lugares.
Vamos experimentar o que as otimizações foram feitas durante o período de compilação e criamos um código que pode ter custos de desempenho.
public class concatenation {public static void main (string [] args) {string userName = "Andy"; String Age = "24"; String job = "desenvolvedor"; String info = nome de usuário + idade + trabalho; System.out.println (info); }}Compilar concatenação.java. Obtenha concatenação.class
javac concatenation.java
Em seguida, usamos o Javap para descompilar o arquivo compilado Concatenation.class. Javap -C Concatenation. Se o comando javap não for encontrado, considere adicionar o diretório em que o Javap está localizado na variável de ambiente ou usando o caminho completo do Javap.
17: 22: 04 -Androidyue ~/Workspace_adt/strings/src $ javap -C ConcatenationCompiled de "concatenação.java" concatenação pública {public concatenation (); Código: 0: Aload_0 1: Invokespecial #1 // Método java/lang/objeto. Código: 0: LDC #2 // String Andy 2: store_1 3: ldc #3 // string 24 5: store_2 6: ldc #4 // String Developer 8: store_3 9: novo #5 // classe Java/lang/stringbuilder 12: Dup 13: Invokespecial #6 // Metoding Java/Lang/Lang/Stringbil InvokeVirtual #7 // Método java/lang/stringbuilder.append: (ljava/lang/string;) ljava/lang/stringbuilder; 20: Aload_2 21: InvokeVirtual #7 // Método java/lang/stringbuilder.append: (ljava/lang/string;) ljava/lang/stringbuilder; 24: Aload_3 25: InvokeVirtual #7 // Método java/lang/stringbuilder.append: (ljava/lang/string;) ljava/lang/stringbuilder; 28: InvokeVirtual #8 // Método java/lang/stringbuilder.toString :() ljava/lang/string; 31: Store 4 33: GetStatic #9 // Campo java/lang/System.out: ljava/io/printStream; 36: Aload 4 38: InvokeVirtual #10 // Método java/io/printstream.println: (ljava/lang/string;) v 41: return}Entre eles, o LDC, a loja, etc. estão as instruções Java ByteCode, semelhantes às instruções de montagem. Os seguintes comentários usam conteúdo relacionado a Java para explicação. Podemos ver que existem muitos stringbuilders, mas nós os chamamos sem exibição no código Java. Esta é a otimização feita pelo compilador Java. Quando o Java Compiler encontra splicing de string, ele criará um objeto StringBuilder. A emenda por trás dele está realmente chamando o método Apênd do objeto Stringbuilder. Dessa forma, não haverá problemas com os quais estamos preocupados.
Otimização do compilador sozinho?
Como o compilador nos ajudou a otimizar, é suficiente confiar apenas na otimização do compilador? Claro que não.
Vejamos um pedaço de código que não foi otimizado para baixo desempenho
public void ImplicticUsEstringBuilder (String [] valores) {String result = ""; for (int i = 0; i <valores.Length; i ++) {resultado += valores [i]; } System.out.println (resultado);}Compilar com Javac e ver com Javap
11: Novo #5 // Classe Java/Lang/StringBuilder 14: DUP 15: Invokespecial #6 // Método Java/Lang/Stringbuilder. java/lang/system.out: ljava/io/printStream; 41: aload_2 42: InvokeVirtual #10 // Método java/io/printStream.println: (ljava/lang/string;) v 45: retornar
Entre eles 8: if_icmpge 38 e 35: goto 5 formam um loop. 8: IF_ICMPGE 38 significa que, se a comparação inteira da pilha de operando da JVM for maior ou igual a (o resultado oposto de i <valores.length) for verdadeiro, salte para a linha 38 (System.out). 35: Goto 5 significa pular diretamente para a linha 5.
Mas há uma coisa muito importante aqui que a criação de objetos de Stringbuilder ocorre entre loops, o que significa que quantas vezes os loops criarão objetos de StringBuilder, o que obviamente não é bom. Código de baixo nível nu.
Otimize -o um pouco para melhorar instantaneamente a qualidade.
public void explicticUsEstringBuilder (String [] valores) {stringbuilder result = new StringBuilder (); for (int i = 0; i <valores.Length; i ++) {resultado.append (valores [i]); }}Informações compiladas correspondentes
Public void explicticUsEstringBuider (java.lang.string []); Código: 0: Novo #5 // Classe Java/Lang/StringBuilder 3: DUP 4: Invokespecial #6 // Método Java/Lang/Stringbuilder. aload_1 18: iload_3 19: aaload 20: InvokeVirtual #7 // Método java/lang/stringbuilder.append: (ljava/lang/string;) ljava/lang/stringbuilder; 23: Pop 24: Iinc 3, 1 27: Goto 10 30: Retorno
Como pode ser visto de cima, 13: if_icmpge 30 e 27: goto 10 formam um loop loop, enquanto 0: o novo #5 está fora do loop, então o StringBuilder não é criado várias vezes.
Em geral, precisamos tentar evitar a criação implícita ou explícita de construtores de cordas no corpo do loop. Portanto, aqueles que entendem como o código é compilado e como ele é executado internamente têm níveis de código relativamente altos.
Se houver algum erro no artigo acima, critique e corrija -os.
O exposto acima é resolver as informações sobre splicing java strings, e continuaremos a adicionar informações relevantes no futuro. Obrigado pelo seu apoio a este site!