2009-12-13 13 views
5
public class A { 

    static String s1 = "I am A"; 

    public static void main(String[] args) { 
     String s2 = "I am A"; 
     System.out.println(s1 == s2); 
    } 
} 

Powyżej wyników programu "prawda". Oba są dwoma różnymi identyfikatorami/obiektami, w jaki sposób dane wyjściowe są "prawdziwe"?Podstawowe pytanie w języku Java: Równość ciągu znaków

Rozumiem, że JVM utworzy różne referencje dla każdego obiektu, jeśli tak, to w jaki sposób dane wyjściowe są prawdziwe?

Odpowiedz

20

Java zarządza literalną pulą String. Ponownie używa tych literałów, kiedy tylko może. Dlatego oba obiekty są w rzeczywistości tym samym obiektem String i zwracają true.

wierzę, że to się nazywa string interning

+1

Aby uzyskać informacje o puli napisów, zajrzyj na wikipedia: http://en.wikipedia.org/wiki/String_interning (+1 ten sam pomysł) –

+1

Tak, literały łańcuchowe są automatycznie internowane, zgodnie z metodyką intern internation API - http : //java.sun.com/javase/6/docs/api/java/lang/String.html – Ash

+1

To nie tylko literały są internowane, ale także stałe w czasie kompilacji. –

1

Nie porównujesz zawartości napisów. Porównujesz referencje obiektu. Powinieneś użyć metody równości (która jest członkiem klasy String). Albo to albo możesz użyć metody compareTo (również w tej samej klasie String), aby sprawdzić, czy zwracana wartość wynosi zero.

Proszę zauważyć, że powyższy tekst stanowił silniejszą sugestię co do pierwotnego stanu pytania, ponieważ okazało się, że OP nie był świadomy faktycznego procesu toczącego się za kulisami.

Inni faceci sugerujący interwencję mieli rację. Aby odpowiedzieć na to pytanie, nie miałem wystarczająco dużo czasu, aby przejść do książki Java Puzzlers. Podejrzewałem coś o ustawianiu tego samego pliku referencyjnego w czasie kompilacji, ale nie wiedziałem, jak znaleźć odniesienie do tego.

+0

Jeśli porównać zawartość wówczas odpowiedź jest zdecydowanie«true»Ale tu zarówno to dwie różne zmienne, wygrał 't jvm utworzyć dwa różne odniesienia? – novice

+1

@Felix.Nie, on porównuje referencje, a wynik jest prawdziwy - co jest dokładnie nieco zaskakującym wynikiem, który spowodował to pytanie –

+2

Dlaczego wy chłopaki nakręciłeś poprawną odpowiedź? –

5

Ponieważ Java Language Specification mówi: literały albo

strunowe, bardziej ogólnie, ciągi są wartości wyrażeń stałych (§15.28) -are "internowany", aby udostępnić unikalne instancje , używając metody String.intern.

6

== sprawdza, czy zmienne wskazują dokładnie to samo wystąpienie obiektu. Dwa utworzone przez ciebie napisy tekstowe wskazują to samo miejsce w pamięci i dlatego są równe. Literały łańcuchowe są internowane, więc ten sam literał ciągu jest tym samym obiektem w pamięci.

Jeśli było zrobić

String s = new String("foo"); 
String t = new String("foo"); 

Następnie == zwróciłby fałszywe i s.equals (t) wróci prawda.

5

To ze względu na optymalizację pamięci wykonywanej przez kompilator ... mianowicie String stałe (tj - String s wykonane przez tego samego String dosłowny) używają tego samego String obiektu od Strings są niezmienne. Operator == sprawdza tylko, czy dwa obiekty są tym samym rzeczywistym obiektem.

Jeśli uda ci się złapać książkę Java Puzzlers autorstwa Joshua Blocha i Neala Gaftera, spójrz na puzzle 13, "Animal Farm" ... ma świetne rady na ten temat. Mam zamiar skopiować jakiś istotny tekst:

"Być może zdajesz sobie sprawę, że stałe kompilacyjne typu String są internowane [JLS 15,28]. Innymi słowy, dowolne dwa stałe wyrażenia typu String, które oznaczają tę samą sekwencję znaków, są reprezentowane przez identyczne odniesienia do obiektów ...Twój kod powinien rzadko, jeśli w ogóle, zależeć od interakcji ciągów stałych. Interning został zaprojektowany wyłącznie w celu zmniejszenia wielkości pamięci maszyny wirtualnej, a nie jako narzędzie dla programistów ... Porównując referencje do obiektów, należy użyć metody equals zamiast operatora ==, chyba że konieczne jest porównanie tożsamości obiektu, a nie wartości .”.

to z powyższym odnośniku wspomniałem ... stronach 30 -. 31 w mojej książce

+1

Wspominałem o tym [przyznawałem, że nie wspomniałem, dlaczego to zrobił] i zostałem za to odrzucony. – monksy

+0

+1 Za wzmiankę o Puzzlerach i wyjaśnienie, dlaczego – monksy

Powiązane problemy