Hvordan kan jeg sammenligne strenge i Java?

Jeg har brugt operatoren == i mit program til at sammenligne alle mine strenge indtil videre. Jeg løb imidlertid ind i en fejl, ændrede en af dem til .equals() i stedet, og det løste fejlen.

Er == dårligt? Hvornår skal den og hvornår skal den ikke bruges? Hvad'er forskellen?

Løsning

== tester for referencegyldighed (om de er det samme objekt).

.equals() tester for værdilighed (om de logisk set er "lige").

Objects.equals() kontrollerer for null, før du kalder .equals(), så du ikke behøver at gøre det (tilgængelig fra JDK7, også tilgængelig i Guava)).

String.contentEquals() sammenligner indholdet af String med indholdet af en hvilken som helst CharSequence (tilgængelig siden Java 1.5).

Hvis du ønsker at teste, om to strenge har samme værdi, skal du derfor sandsynligvis bruge Objects.equals().

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

Du vil næsten altid bruge Objects.equals(). I den sjældne situation, hvor du ved at du har med interned strenge at gøre, kan du kan bruge ==.

Fra JLS 3.10.5. String Literals:

Desuden henviser en strenglitteral altid til samme instans af klassen String. Dette skyldes, at strenglitteraler - eller mere generelt strenge, der er værdier af konstante udtryk (§15.28)) - er "interned" så de deler unikke instanser ved hjælp af metoden String.intern.

Lignende eksempler kan også findes i JLS 3.10.5-1.

Kommentarer (0)

Ja, == er dårligt til sammenligning af strenge (og egentlig alle objekter, medmindre du ved, at de er kanoniske). == sammenligner bare objektreferencer. .equals() tester for lighed. For Strings vil de ofte være ens, men som du har opdaget, er det ikke altid garanteret.

Kommentarer (0)

== sammenligner objektreferencer i Java, og det er ingen undtagelse for String-objekter.

For at sammenligne det faktiske indhold af objekter (herunder String) skal man bruge equals-metoden.

Hvis en sammenligning af to String-objekter ved hjælp af == viser sig at være true, skyldes det, at String-objekterne blev internaliseret, og at Java Virtual Machine får flere referencer til at pege på den samme instans af String. Man bør ikke forvente, at sammenligning af et String-objekt, der indeholder det samme indhold som et andet String-objekt ved hjælp af ==, vil blive evalueret som true.

Kommentarer (0)