2013-03-15 12 views
5

wszystkim I pojawił się kolejny problem gdy napisać poniższy kodzamieszanie o java String dosłownym basenem i konkatenacji STRING

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)); 

potem uruchomić mój kod i wydrukować konsoli to

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

to bardzo mnie zdezorientowało. dlaczego drugi druk TRUE, ale pierwszy wydruk FALSE ?? w moim zrozumieniu puli literowej String, gdy zdefiniowany łańcuch i JVM sprawdzi, czy pula zawiera ten ciąg, jeśli nie, umieść ciąg w puli.
w moim kodu, zmienna cześć istnieje w basenie smyczkowy”Helo«i»lo«również w basenie, moje pytanie jest

  1. jeśli wynik konkatenacji»Helo "i" lo "istnieje w puli.
  2. jaka jest różnica między definicją str5 a str10s i dlaczego nie są "=="? ? Nie STR5 i str10 odnoszą się do mówią jest "Witam”, że w basenie String («==» wydaje się oznaczać odniesienia jest taki sam przedmiot)

moja wersja JDK: 1.6.0_29
mój IDE: IntelliJ IDEA 11,2

ktoś może wskazać ją bardzo dziękuję

Odpowiedz

7

zachowuje się jak powinna ona skierowana jest w dwóch odcinkach JLS

JLS #3.10.5:?..

ciągi będące wartościami wyrażeń stałych (§15.28) - są "internowane", aby współdzielić unikalne instancje, używając metody String.intern.

JLS #15.28 wymienia to, co jest traktowane jako wyrażenie ciągłe. W szczególności, literały łańcuchowe są wyrażeniami stałymi ("Hel" i "lo"), ale aby zmienna była uważana za stałą, musi być ostateczna.

W twoim przypadku, jeśli zmienisz kod nieznacznie aby str8 i str9 stałą, dostaniesz true trzykrotnie:

final String str8 = "Hel"; 
final String str9 = "lo"; 
+0

dziękuję!to mi bardzo pomaga – fuye

-1

Jesli porównać dwa ciągi używać string.equals nie string1 == string2

spróbować :

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

tak, jak widzimy w kodzie źródłowym równa się kod źródłowy, najpierw sprawdź, czy (this == anObject) {return true;}, a następnie sprawdź, czy jest to instancja łańcucha, jeśli tak, porównaj zawartość dwóch obiektów typu string. – fuye

0

Kod ma następujące punkty do rozważenia:

String hello = "Hello"; 

tutaj „Witam” jest dosłownym przypisane odniesienia cześć więc dosłownym ma własną hashcode

String str5 = "Hel" + "lo"; 

tutaj „Hel” + „lo” są 2 literałami połączono i przyporządkowane odniesienia cześć zatem Nowy dosłownym jest taki sam jak pierwszy, a tym samym samego hashcode

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

tutaj str8 + STR9 są 2 odniesienia, które łączą się i przejść do nowej odniesieniu cześć zatem nowy dosłownym ma własną 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)); 

gdy używasz == dopasowuje się przez kod skrótu i ​​wartość. a więc niedopasowanie.

spróbuje użyć

string_1.equals (STRING_2)

zamiast

STRING_1 == STRING_2

a dostaniesz tylko wartość dopasowanie . więc wszystko prawda

Patrz poniżej odpowiedź również (od What is the difference between == vs equals() in Java?):

equals() metoda porównuje „wartość” wewnątrz instancji String (na stosie), niezależnie czy dwa (2) odniesienia obiektów odnoszą do tej samej instancji String, czy nie. Jeśli dowolne dwa (2) odwołania do obiektów typu String odnoszą się do tej samej instancji String, to świetnie! Jeśli dwa (2) odwołania do obiektów odnoszą się do dwóch (2) różnych instancji String, nie ma to znaczenia. Jest to "wartość" (czyli: zawartość tablicy znaków) wewnątrz każdej instancji String, która jest porównywana.

Z drugiej strony operator "==" porównuje wartość dwóch odwołań do obiektów, aby sprawdzić, czy odnoszą się one do tej samej instancji String. Jeśli wartość obydwu odwołań do obiektu "odwołuje się do" tej samej instancji String, to wynikiem wyrażenia boolowskiego będzie "true". Duh. Jeśli, z drugiej strony, wartość obu odwołań do obiektu odnosi się do różnych instancji String (nawet jeśli obie instancje String mają identyczne "wartości", to znaczy zawartość tablic znaków każdej instancji String jest taka sama) wynikiem wyrażenia boolowskiego będzie "fałsz".

+1

Przykro mi, ale nie rozumiem, że "używaj == dopasowuje się przez kod skrótu i ​​wartość",
Drukuję każdy hashcode str5, str8, str9, str10 jest to hello.hash-> 69609650; str8.hash-> 72431; str9.hash-> 3459; str10.hash-> 69609650; str5.hash-> 69609650; jak widzimy, hashcode str5, str10 dokładnie ten sam kod, ale str5 == str10 zwraca false; – fuye

+0

proszę sprawdzić edytowaną odpowiedź –

+0

dziękuję za poświęcenie czasu na pisanie tego. To wymyślić moje pomylenie między "==" i "równa się". Bardzo wdzięczny – fuye

0
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.