Der durchschnittliche Programmieranfänger wird davon ausgehen, dass er Zeichenketten auch einfach mit == wie doubles, longs, chars, … vergleichen kann. Dies stimmt so aber nicht. Das beweist ein kleiner Test:
String str1 = new String("Hallo");
String str2 = new String("Hallo");
if (str1 == str2) {
System.out.println("str1 entspricht str2");
}
else {
System.out.println("str1 ist anders als str2");
}
Anders als Sie erwartet haben, wird nicht „str1 entspricht str2“ ausgegeben, sondern „str1 ist anders als str2“. Aber wie kann das funktionieren? In str1 und in str2 steht doch das Selbe!? Das ist soweit auch korrekt. Ein == überprüft aber nicht etwa den Inhalt zweier Objekte, sondern lediglich deren Referenz. D. h. wenn beide Objekte wirklich auf denselben Platz im Arbeitsspeicher verweisen, dann ist diese Abfrage wahr. Ansonsten nicht. Auch dieser Sachverhalt lässt sich einfach demonstrieren.
String str1 = new String("Hallo");
String str2 = str1;
if (str1 == str2) {
System.out.println("str1 entspricht str2");
}
else {
System.out.println("str1 ist anders als str2");
}
Durch die Zuweisung str2 = str1 erhält str2 eine Referenz auf str1. Somit verweisen beide Objekte auf dieselbe Stelle im Arbeitsspeicher und es wird „str1 entspricht str2“ ausgegeben.
Um zwei Zeichenketten auf inhaltliche Gleichheit zu überprüfen, wird die Methode equals() verwendet:
String str1 = new String("Hallo");
String str2 = new String("Hallo");
if (str1.equals(str2)) {
System.out.println("str1 entspricht str2");
}
else {
System.out.println("str1 ist anders als str2");
}
Dies gilt übrigens für alle Objekte und nicht nur für Strings. Daher merken Sie sich folgenden Satz gut: primitive Datentypen und Referenzen werden mit ==, Objekte mit equals verglichen!
Wenn Sie Zeichenketten vergleichen wollen, ohne auf Groß-/Kleinschreibung zu achten, greifen Sie auf die Methode equalsIgnoreCase() zurück.
String str1 = new String("hAlLo");
String str2 = new String("Hallo");
if (str1.equals(str2)) {
System.out.println("str1 entspricht str2");
}
else if (str1.equalsIgnoreCase(str2)) {
System.out.println("str1 entspricht str2 - wenn die "+
"Groß-/Kleinbuchstaben ignoriert werden.");
}
String-Pool
Kompilieren Sie folgendes:
String str = "abc"; String str2 = "abc"; System.out.println(str == str2);
Zu Ihrer Verwunderung werden Sie feststellen, dass die Ausgabe dieses Codestücks true ist. Dies liegt daran, dass Java intern einen Pool für Zeichenketten verwendet. Verwenden Sie einen String, der bereits im Programm existiert (in diesem Fall verwendet str2 die selbe Zeichenkette wie str), wird kein neuer String erzeugt, sondern der String aus dem Pool zugewiesen. Dadurch verweisen auch wirklich beide Zeichenketten auf die selbe Stelle im Pool.
Dies funktioniert aber nur, wenn der String nicht über new initialisiert wurde, und bereits beim Kompilieren bekannt ist (also nicht durch bspw. eine Benutzereingabe ins Programm gelangt).
String str = "abc";
String str2 = new String("abc");
System.out.println(str == str2);
Der Vergleich von Zeichenketten mit == ist zwar möglich, aber unsicher. Verwenden Sie deshalb immer zum Vergleich die equals-Methode! Gleichzeitig sollten Sie bei Strings auf das new Schlüsselwort verzichten, da eine Verwendung der Strings aus dem Pool effizienter ist.
