O que faz a comparação de referência (==) funcionar para algumas cadeias de caracteres em Java?

Eu tenho as seguintes linhas de códigos para comparar String. str1 não é igual a str2, o que é compreensível, pois compara a referência de object. Mas então por que s1 é igual a s2?

String s1 = "abc"; String s2 = "abc"; String str1 = new String("abc"); String str2 = new String("abc"); if (s1==s2) System.out.println("s1==s2"); else System.out.println("s1!=s2"); if (str1==str2) System.out.println("str1==str2"); else System.out.println("str1!=str2"); if (s1==str1) System.out.println("str1==s1"); else System.out.println("str1!=s1"); 

Saída:

  s1==s2 str1!=str2 str1!=s1 

O conjunto constante de strings armazenará essencialmente todos os literais de string, então eles são o mesmo object abaixo, e é por isso que você vê a saída que você faz para s1==s2 . É essencialmente uma otimização na VM para evitar a criação de um novo object de string toda vez que um literal é declarado, o que pode ficar muito caro muito rapidamente! Com o seu exemplo str1==str2 , você está explicitamente dizendo à VM para criar novos objects de string, por isso é falso.

Como um aparte, chamar o método intern() em qualquer string irá adicioná-lo ao conjunto constante (e retornar a String que foi adicionada ao pool.) Não é necessariamente uma boa idéia fazer isso, a menos que você tenha certeza de que Estamos lidando com seqüências de caracteres que definitivamente serão usadas como constantes, caso contrário, você pode acabar criando dificuldades para rastrear vazamentos de memory.

s1 e s2 são literais de string. Quando você cria um novo literal de String, o compilador primeiro verifica se algum literal representando o mesmo está presente no conjunto de cadeias ou não. Se houver um presente, o compilador retorna esse literal, caso contrário, o compilador cria um novo.

Quando você criou String s2 o compilador retorna a String s1 do pool, como já foi criado anteriormente. Essa é a razão pela qual s1 e s2 são iguais. Esse comportamento é chamado de internação .

Este fenômeno é devido a internação de String .

Basicamente, todos os literais de string são “armazenados em cache” e reutilizados.

Isso ocorre porque os literais de string estão sendo internados. Nesta matéria, as documentações de Java dizem:

Todas as strings literais e expressões constantes com valor de string são internadas

E isso explica porque s1 e s2 são iguais (essas duas variables ​​apontam para a mesma string internada)

Em Java, as mesmas seqüências de caracteres constantes serão reutilizadas. Então, s1 e s2 apontam para o mesmo object “abc” e s1==s2 . Mas quando você usa new String("abc") , outro object será criado. Então, que s1 != str1 .

Como string é imutável em java, todos os string literals armazenados em cache para a reutilização.

Quando você cria o object String usando o operador new (), ele sempre cria um novo object na memory heap. Por outro lado, se você criar um object usando a syntax literal de string, por exemplo, “Java”, ele pode retornar um object existente do conjunto String (um cache do object String no espaço Perm gen, que agora é movido para o espaço heap na liberação recente do Java) , se já existe. Caso contrário, ele criará um novo object de string e colocará o pool de string para reutilização futura.

 String s1 = new String("java"); String s2 = new String("java"); String s3 = "java"; String s4 = "java"; 

insira a descrição da imagem aqui

Por favor, consulte este link