publicclassTestclass{publicstaticvoid main (String[] args ){String ersteswort;
ersteswort=newString();
ersteswort ="Hallo";String zweiteswort;
zweiteswort =newString();
zweiteswort ="Hallo";if(ersteswort == zweiteswort){System.out.println("Wir haben die gleichen Referenzen");}else{System.out.println("Wir haben unterschiedliche Referenzen");}if( ersteswort.equals(zweiteswort)){System.out.println("Unsere String-Objekt-Inhalte sind gleich");}else{System.out.println("Unsere String-Objekt-Inhalte sind nicht gleich");}}}
Ich dachte, für "ersteswort" und "zweiteswort" werden zwei unterschiedliche Objekte auf dem Heap erzeugt (mit gleichem Inhalt).
Demzufolge hätte der Vergleich "ersteswort == Zweiteswort" -> "false" liefern müssen, da sie auf unterschiedliche Objekte referenzieren.
Leider bekomme ich folgende Antwort... why?
Code:
Wir haben die gleichen Referenzen
Unsere String-Objekt-Inhalte sind gleich
Nein, das ist nicht ganz richtig.
Es gibt intern noch einen Stringpool. Für den String "Hallo" wird ein String erzeugt der im Stringpool liegt, deine beiden Referenzen ersteswort und zweiteswort zeigen damit auf den selben String.
Java:
ersteswort=newString();
ersteswort ="Hallo";
Das ist übrigens sinnlos, die Zuweisung
Code:
new String();
hat kein Gewicht, weil sie direkt wieder überschrieben wird. Oder meinst du sowas :
Acsho, das mit dem Stringpool wusste ich nicht.
Dachte Strings werden genau so behandelt wie "Objekte" bzw. sind Objekte der Klasse "String".
Wollte mit dem Ausdruck:
Code:
String ersteswort;
ersteswort= new String();
ersteswort = "Hallo";
explizit darauf hinweisen, dass Strings genau wie Objekte erzeugt werden und dass das gleiche ist wie
Code:
String ersteswort = "Hallo"
Aber anscheinend stimmt das ja nicht. Und das Ergebnis vom Referenzvergleich liefert auch was anders.
Deine Antwor mit "Stringpool" stellt meine ganzen String-Vorstellungen auf dem Kopf.
Das ist übrigens sinnlos, die Zuweisung new String(); hat kein Gewicht, weil sie direkt wieder überschrieben wird. Oder meinst du sowas :
Kannst du mir vllt. erklären was ich hier überschrieben habe??
Code:
String ersteswort; // deklareation der Variablennamn für Stringtypen
ersteswort= new String(); // Es wird ein String Objekt erzeugt und der Variable ersteswort zugewiesen
ersteswort = "Hallo"; // Inhalt des referenzienten Objekts mit "Hallo" füllen
Ja, ist richtig. Nur dass eben noch ein Pool von Strings verwaltet wird. Stell dir vor du hast in deinem Quellcode sehr viele "" oder " " stehen. Da wärs ja quatsch für jeden solchen String ne eigene Instanz zu haben. Das wird dann durch den String pool optimiert.
Ne weitere Besonderheit ist, dass du Strings nicht explizit per new erzeugen musst:
String ersteswort; // deklareation der Variablennamn für Stringtypen
ersteswort= new String(); // Es wird ein String Objekt erzeugt und der Variable ersteswort zugewiesen
ersteswort = "Hallo"; // Inhalt des referenzienten Objekts mit "Hallo" füllen
Die letzte Zeile stimmt nicht. Mit einer Zuweisung rührst du das Objekt, das hinter der Variable steckt, nicht an. Stattdessen wird die Referenz auf das neu zugewiesene Objekt umgeleitet. Das alte Objekt wird nun einfach nicht mehr von dieser Variable referenziert.
Ja, das stimmt....wär echt nicht logisch für jeden String ein Objekt zu erzeugen.
Die letzte Zeile stimmt nicht. Mit einer Zuweisung rührst du das Objekt, das hinter der Variable steckt, nicht an. Stattdessen wird die Referenz auf das neu zugewiesene Objekt umgeleitet. Das alte Objekt wird nun einfach nicht mehr von dieser Variable referenziert
Verstehe...! Das alte Stringobjekt , das ich mit new String () erzeugt habe wird mit der neuen Zuweisung ersteswort = "Hallo" futter für Garbage Collector.
Man kann auch bei dynamischen Strings erzwingen, dass sie in den Pool wandern (bzw. aus diesem genommen werden, falls schon existent). Das geht per [c]String#intern()[/c]:
ich denke das es wichtig ist zu erwähnen das Strings immutable sind. Also unveränderlich. Dies bedeutet, dass jede Operation, die einen String verändert, einen neuen String liefert. Nur dadurch ist es möglich die Strings zu poolen. Ansonsten würde es zu unabsehrbaren Nebenwirkungen kommen, wenn sich im programmteil eins ein Steingut ändert u dies auf mal Auswirkungen auf ganz andere Programmteile hat.
== vergleicht die Adressen der Strings und würde damit sagen, dass text1 identisch (heisst an derselben Speicheradresse stehend) mit text2 ist, und das ist in der Praxis leider meistens wertlos :-D
Falls Du wissen willst, ob ein String grösser / kleiner / auch gleich einem anderen ist, musst du compareTo nehmen:
Code:
if (text1.compareTo( text2 ) > 0) { // text2 ist grösser als text1 ...
..äähm, korrekt heisst es "kommt bei Vergleich der Unicodes lexikographisch nach text1" statt "grösser als"...
Genau das habe ich geschrieben. Deine beiden Hallos sind IDENTISCH, weil der Compiler die Konstante nur einmal ablegt.
Deshalb haben sie auch die gleiche Adresse. Wenn der Compiler die Konstanten anders implementiert, zum Beispiel nicht platzoptimiert, ist es mit dem == wieder Essig.
Stringvergleiche mit == sind und bleiben Quatsch.
Und die Ausnutzung eines systeminternen (damit von der JVM - Implementierung abhängigen) Mechanismus in realen Programmen ist höchst fragwürdig.
wo er aber dennoch recht hat ist, dass man sich nicht auf den StringPool verlassen sollte und denken "naja, dann kann ich ja Strings per == vergleichen". Strings sind Objekte und daher sollte man auf Gleichheit NUR mit equals vergleichen. Wenn man auf Identitaet vergleichen will, dann kann man == nehmen.
Also - immer mit equals nehmen und den Stringpool zwar wissen, aber nicht sich darauf verlassen.
wo er aber dennoch recht hat ist, dass man sich nicht auf den StringPool verlassen sollte und denken "naja, dann kann ich ja Strings per == vergleichen". Strings sind Objekte und daher sollte man auf Gleichheit NUR mit equals vergleichen. Wenn man auf Identitaet vergleichen will, dann kann man == nehmen.
Also - immer mit equals nehmen und den Stringpool zwar wissen, aber nicht sich darauf verlassen.
Genau. Bitte auch daran denken, dass wir im Anfängerforum sind. Der ganze Thread gehört eher unter "Java- Philosphie für Fortgeschrittene...". Irgendeiner nimmt das wörtlich.