uma confusão sobre o pool literal de java String e a concatenação de String

tudo, eu enfrentei um problema quando escrevi o código abaixo

String hello = "Hello"; String str5 = "Hel" + "lo"; String str8 = "Hel"; String str9 = "lo"; String str10 = str8 + str9; System.out.println("str10==hello?" + (str10 == hello)); System.out.println("str5==hello?" + (str5 == hello)); System.out.println("str10==str5?" + (str10 == str5)); 

então eu corro meu código e o console imprime isso

 str10 == hello ? false str5 == hello ? true str10 == str5 ? false 

isso me confundiu muito. porque a segunda impressão TRUE mas a primeira impressão FALSE ?? na minha compreensão do conjunto literal de cadeias, quando uma cadeia de caracteres é definida e a JVM verificará se o conjunto contém essa cadeia, se não, coloque a cadeia no conjunto.
no meu código, variável hello existe no pool de strings, ” Helo ” e ” lo ” também no pool, minha pergunta é

  1. se o resultado da concatenação de ” Helo ” e ” lo ” existir no pool.
  2. qual é a diferença entre a definição sobre str5 e str10s ‘, e porque eles não são “==”? str5 e str10 referem-se ao diferente ” Hello ” que no conjunto de strings? (“==” parece significar que a referência é o mesmo object)

minha versão do jdk: 1.6.0_29
meu IDE: Intellij Idea 11.2

Alguém pode apontar isso? Muito obrigado

Ele se comporta como deveria. Ele é abordado em duas seções do JLS.

JLS # 3.10.5 :

strings que são os valores de expressões constantes (§15.28) – são “internados” para compartilhar instâncias exclusivas, usando o método String.intern.

O JLS # 15.28 lista o que é considerado como uma expressão constante. Em particular, os literais de string são expressões constantes (“Hel” e “lo”), mas para que uma variável seja considerada uma constante, ela precisa ser final.

No seu caso, se você alterar um pouco seu código para tornar str8 e str9 constantes, você será true três vezes:

 final String str8 = "Hel"; final String str9 = "lo"; 
 String hello = "Hello"; // at compile time string is known so in String Constant Pool String str5 = "Hel" + "lo"; // at compile time string is known so in String Constant Pool same object as in variable hello String str8 = "Hel"; // at compile time string is known so in String Constant Pool String str9 = "lo"; // at compile time string is known so in String Constant Pool String str10 = str8 + str9; // at runtime don't know values of str8 and str9 so in String Constant Pool new object different from variable hello str10 == hello ? false // as str10 has new object and not the same as in hello str5 == hello ? true // both were created at compile time so compiler know what's the result in str5 and referenced the same object to str5 as in hello str10 == str5 ? false // str10 is a different object, hello and str5 are referenced same object as created at compile time. 

O código tem os seguintes pontos a serem considerados:

 String hello = "Hello"; 

Aqui “Hello” é um literal atribuído a referência hello, assim, o literal tem seu próprio hashcode

 String str5 = "Hel" + "lo"; 

Aqui “Hel” + “lo” são 2 literais combinados e atribuídos a referência hello, assim, o novo literal é o mesmo que o primeiro e, portanto, o mesmo hashcode

 String str8 = "Hel"; String str9 = "lo"; 

Aqui str8 + str9 são 2 referências que combinam e apontam para uma nova referência hello, assim, o novo literal tem seu próprio hashcode

 String str10 = str8 + str9; System.out.println("str10==hello?" + (str10 == hello)); System.out.println("str5==hello?" + (str5 == hello)); System.out.println("str10==str5?" + (str10 == str5)); 

quando você usa ==, ele combina com código hash e valor. assim, a incompatibilidade.

tente usar

string_1.equals (string_2)

ao invés de

string_1 == string_2

e você obterá apenas correspondência de valor. assim tudo verdade

Por favor, consulte a resposta abaixo também (de Qual é a diferença entre == vs equals () em Java? ):

O método equals () compara o “valor” dentro de instâncias de String (no heap), independentemente de as duas (2) referências de objects referirem-se à mesma instância de String ou não. Se quaisquer duas referências de objects do tipo String se referirem à mesma instância de String, então ótimo! Se as duas (2) referências a objects se referirem a duas (2) instâncias de String diferentes, isso não fará diferença. É o “valor” (isto é: o conteúdo do array de caracteres) dentro de cada instância de String que está sendo comparada.

Por outro lado, o operador “==” compara o valor de duas referências de objects para ver se elas se referem à mesma instância de String. Se o valor de ambas as referências a objects “referirem-se” à mesma instância de String, o resultado da expressão booleana seria “true” .. duh. Se, por outro lado, o valor de ambas as referências de object “referir-se a” instâncias de String diferentes (embora ambas as instâncias de String tenham “valores” idênticos, ou seja, o conteúdo das matrizes de caracteres de cada instância de String seja o mesmo) O resultado da expressão booleana seria “falso”.

Se u comparar duas strings use string.equals não string1 == string2

tente:

 System.out.println("str10==hello?" + (str10.equals(hello));