Datentypen Stringvergleich mit ==

B

blubbermann

Gast
Hallo,

da es sich bei String ja um einen Referenzdatentyp handelt soll man ja die Gleichheit von Strings mittels equals überprüfen. Wieso liefert aber sowas wie


String a ="Hallo";
String b="Hallo";

if(a==b) { ...}


Ggf. trotzdem true obwohl hier ja Referenzen und nicht der Inhalt verglichen werden. Die Referenzen dürften ja eigentlich nicht gleich sein.
 

DrPCox

Mitglied
Ich denke, dass es geht, dass die Gleichheit zweier Dinge geprüft wird und nicht, ob es sich um ein und dasselbe Ding handelt...Also mal so aus der Sicht eines Anfängers gesehen.
 
B

blubbermann

Gast
Hi,

kannst du das mit dem String Pool mal erklären?

Also String a = new String("bla");String b = new String("bla"); if(a==b) würde false liefern, da unterschiedliche Referenzen. Wenn ich die Literalnotation

String a = "bla"; und String b = "bla"; nutze wird if(a==b) aber true. Das hab ich nicht vertanden. Adressen sollten unterschiedlich sein.
 

Landei

Top Contributor
Richtig, aber hier "mogelt" die JVM eben: Da Strings unveränderlich sind, macht es (bis auf das Verhalten von ==) keinen Unterschied, intern zwei "gleiche" Strings stillschweigend durch einen einzigen zu ersetzen. Man kann leicht zeigen, dass das nicht immer klappt, z.B. gibt

Java:
String s1 = new String("hallo");
String s2 = new String("hallo");
System.out.println(s1 == s2);

"false" aus.

Mit dem StringPool kann man sich das vereinfacht so vorstellen: Ein String-Literal wie "hallo" wird von der JVM nicht stupide durch new String(new char[]{'h','a','l','l','o'}) ersetzt, sondern erst nachgeschaut, ob es einen derartigen String schon "im Pool" gibt, und dann dessen Referenz eingesetzt. Gibt es den String nicht, wird er neu erzeugt und referenziert, aber auch "in den Pool" geworfen und wiederverwendet, falls sich später nochmal der gleiche String finden sollte.
 
Zuletzt bearbeitet:
B

blubbermann

Gast
Hmm, evtl. habt ihr da nochn paar Links. Warum nur bei new die Referenzen verschieden sind erschließt sich mir leider noch immer nicht.
 
G

gman

Gast
Weil bei "new" explizit ein neues Objekt erzeugt wird, da guckt die JVM gar nicht erst nach ob
so ein String schon irgendwo existiert. Kann sie auch gar nicht weil es für Objekte eben nicht
so einen Pool gibt wie ihn die anderen Poster schon beschrieben haben.

Wenn du die Strings durch die Literale erzeugst denkt sich die JVM:

"Hmm, muss ich nicht unbedingt neu machen. Prima, dann guck ich doch mal ob ich
sowas schon habe."
 

knoppers

Bekanntes Mitglied
Diese Problem tritt nicht nur bei String auf. Es ist auch bei Integer und Double Objekten so. Das vergleichen von Objekte mit == sollte man vermeiden, da eigentlich nicht der Wert verglichen wird sondern das Objekte mit Adresse. Die JVM hat hier ein Mango was nicht ganz so richtig ist. Ich denke mal das kommt vom Autoboxing Bsp. " Integer -> int " oder " int -> Integer ". So etwas sollte man dann z.B. so lösen.

Java:
int a = 0;
Integer b = 1;
if (b.equals.(Integer.valueOf(a)) {
...
}

String a = "abc";
String b = new String("abc");

if (String.valueOf(a).equals(b)) {
....
}

Wenn man es sauber lösen will sollte man nur mit Objekten arbeiten. Ausnahmen sind Zähler in Schleifen, wie z.B.

Java:
for(int index = 0; index < max; index++) { ... }

Für solche Sachen sollte man die primitiven Datentypen noch nehmen, sonst nicht.
 
Zuletzt bearbeitet:

faetzminator

Gesperrter Benutzer
Für solche Sachen sollte man die primitiven Datentypen noch nehmen, sonst nicht.

Wenn ich nirgends ausser bei Schleifen primitive Datentypen verwenden soll, warum genau da? Immerhin kann ich es dort auch mit einem Integer lösen ;)
Ich teile knoppers' Meinung nicht. Meiner Meinung nach stellen primitive Datentypen im Code kein Problem dar (dank Autoboxing etc. auch ganz ok mit Generics) - im Gegensatz zu Arrays (ausser in "Low Level"-Code wie ArrayList Impl.).
 

knoppers

Bekanntes Mitglied
Okay. Gut das ist natürlich Ansichtssache. Man kann natürlich auch Objekte in Schleifen als Zähler verwenden. Primitive Datentypen sind halt schneller in der Verarbeitung aber nicht so sicher. Letztendlich muss das jeder selber entscheiden, Beziehungsweise bei Projekten der Projektleiter entscheiden, wann und wo primitive Datentypen verwendet werden dürfen oder sollen.
 

nroz

Mitglied
Und wenn du
Java:
String s1 = new String("Hallo");
schreibst, werden gleich 2 String-Objekte erzeugt und nur eines genutzt.

Zieht also auch wieder an der Performance falls man sowas in einer Schleife machen sollte. ;-)
 

faetzminator

Gesperrter Benutzer
Primitive Datentypen sind halt schneller in der Verarbeitung aber nicht so sicher.
Ersteres, klar. Wenn wohl auch nur minim (Autoboxing mal aussen vor gelassen). Aber was soll bei einem int sicher bzw. nicht sicher sein?
Letztendlich muss das jeder selber entscheiden, Beziehungsweise bei Projekten der Projektleiter entscheiden, wann und wo primitive Datentypen verwendet werden dürfen oder sollen.
Also, wenn "meine" Projektleiter für mich entscheiden würden, wie ich zu coden hätt, dann würden wohl keine Projekte realisiert werden :lol:
 

faetzminator

Gesperrter Benutzer
Ich frag mich noch immer, was du damit meinst.
1. primitive Typen können keine NPE's schmeissen (klar, gibt keine [c]null[/c]-Referenz...)
2. Berechnungen mit diesen sind Threadsafe, da nicht mehr als ein Takt verwendet wird...
Ob du nun primitive Datentypen oder die Wrapper-Klassen vorziehst, ist ganz dir überlassen. Verstehen tu ich es trotzdem nicht.
 

Landei

Top Contributor
Für solche Sachen sollte man die primitiven Datentypen noch nehmen, sonst nicht.

So ein Käse! Natürlich nehme ich primitive Datentypen, wenn ich ein großes Array benötige, eine Complex-Klasse schreiben will oder eine Nullstelle nach dem Newton-Verfahren finden will.

Problematisch ist vor allem das Typsystem, z.B. das primitive Typen nicht als generische Parameter zugelassen sind, dass ein int[] nicht als Integer[] verwendet werden kann u.s.w. Mit etwas Aufwand ließe sich das komplett "verbergen", so dass der Compiler entscheidet, ob man nun int oder Integer nimmt (Scala macht das so, und soweit ich weiß gab es in Smalltalk noch nie primitive Datentypen, also müssen sie intern auch gezaubert haben). Einige Sprachen gehen sogar noch weiter und haben einen Numerical Tower, wo es nur noch einen unbeschränkten Datentyp ähnlich BigInteger gibt - nur dass für kleine Werte aus Effizienzgründen doch wieder beschränkte Datentypen eingesetzt werden, allerdings vollständig transparent.
 

faetzminator

Gesperrter Benutzer
Da stimme ich dir zu!

Problematisch ist vor allem das Typsystem, z.B. das primitive Typen nicht als generische Parameter zugelassen sind, [...]
Dank Autoboxing wie bereits erwähnt aber nicht weiter schlimm.
[...] dass ein int[] nicht als Integer[] verwendet werden kann u.s.w.
... und genau das wär wieder ein Problem mit Arrays, nicht mit primitiven Datentypen. Immerhin kennt man diese Probleme auch mit Arrays und verschiedenen Typen...
 

Ähnliche Java Themen

Neue Themen


Oben