-
Strings in switch vs. Stringvergleich
Autor: monettenom 20.03.14 - 11:42
Tückisch ist ja folgendes in Java:
String value = "test";
if (value == "test")
; // wird nie erreicht
if(value.equals("test"))
; // schon besser
Beim switch muss das equals() ja implizit ausgeführt werden, damit es klappt, warum also nicht auch beim ==? -
Re: Strings in switch vs. Stringvergleich
Autor: Shore 20.03.14 - 12:07
Ist das in anderen typisierten Programmiersprachen anders?
-
Re: Strings in switch vs. Stringvergleich
Autor: non_sense 20.03.14 - 12:19
Weil der Vergleichsoperator == eine andere Bedeutung hat.
Der Vergleichsoperator == vergleicht bei Objekten die Referenzen, sprich die Zeiger auf das Objekt, und die sind bei zwei unterschiedlichen Objekten nun mal unterschiedlich. Bei elementaren Datentypen vergleicht der Operator den tatsächlichen Wert. Das hat damit zu tun, wo die JVM die Daten speichert. Elementare Datentypen laden im Stack, während Objekte im Heap landen.
Die Equals()-Methode an einem String testet hingegen den Inhalt des Strings, und nicht die Referenz. Anders als in anderen Sprachen (z.B. C#) lassen sich unter Java die Operatoren nicht überladen. Deswegen muss bei einem String-Vergleich die Equals()-Methode verwendet werden.
Das switch()-Statement arbeitet ja ganz anders als ein Vergleichsoperator und kann deshalb auf die jeweiligen Objekte reagiert. Deswegen kann hier implizit die Equals()-Methode der jeweiligen Objekte aufgerufen werden.
Unter C# kann man tatsächlich beides benutzen, weil der Vergleichsoperator == in der String-Klasse überladen wurde.
1 mal bearbeitet, zuletzt am 20.03.14 12:24 durch non_sense. -
Re: Strings in switch vs. Stringvergleich
Autor: non_sense 20.03.14 - 12:20
Shore schrieb:
--------------------------------------------------------------------------------
> Ist das in anderen typisierten Programmiersprachen anders?
Ja und Nein.
In einigen Sprachen kann man die Vergleichsoperatoren überladen, sodass man mittels == implizit Equals() aufruft. -
Re: Strings in switch vs. Stringvergleich
Autor: monettenom 20.03.14 - 12:56
Wusste ich schon und geht am Thema vorbei.
Mir geht es darum, dass es inkonsistent ist. Einmal werden Referenzen verglichen ein anderes mal Inhalte.
Dass bei value == "test" kein Stringvergleich ist, ist nicht sehr intuitiv und wird häufig falsch gemacht. Dass nun Strings bei switch()-Anweisungen verwendet werden können, bei Vergleichen aber nicht, macht das nicht besser. -
Re: Strings in switch vs. Stringvergleich
Autor: MeiSign 20.03.14 - 13:48
monettenom schrieb:
--------------------------------------------------------------------------------
> Mir geht es darum, dass es inkonsistent ist. Einmal werden Referenzen
> verglichen ein anderes mal Inhalte.
>
> Dass bei value == "test" kein Stringvergleich ist, ist nicht sehr intuitiv
> und wird häufig falsch gemacht.
Das kommt glaube ich ganz darauf an von welchem Hintergrund du zu Java gekommen bist. Fuer mich ist das absolut intuitiv das ich mit dem == Operator keine Strings vergleichen kann sondern nur die Referenzen. Und sehr oft falsch gemacht wird das glaube ich nicht. Jeder der professionell mit Programmiersprachen arbeitet bekommt das im 1x1 seiner Ausbildung/Fortbildung/Studium beigebracht. Ich erinnere mich sogar, dass es so ziemlich das erste Thema im Informatik Schulunterricht war.
1 mal bearbeitet, zuletzt am 20.03.14 13:49 durch MeiSign. -
Re: Strings in switch vs. Stringvergleich
Autor: non_sense 20.03.14 - 14:04
MeiSign schrieb:
--------------------------------------------------------------------------------
> Jeder der professionell
> mit Programmiersprachen arbeitet bekommt das im 1x1 seiner
> Ausbildung/Fortbildung/Studium beigebracht. Ich erinnere mich sogar, dass
> es so ziemlich das erste Thema im Informatik Schulunterricht war.
Jop, bei mir auch.
Und inkonsistent ist es auch nicht. Das hat einfach damit zu tun, wie der Stack und der Heap funktionieren. Den Stack rufen wir per Call-By-Value auf und den Heap per Call-By-Reference. Das Dereferenzieren tut Java implizit schon für uns, deswegen brauchen wir hier nicht mit Zeigerarithmetik rumhantieren. Der Vergleichsoperator vergleicht also die Werte, die er bekommt und dass ist beim Stack der Wert und beim Heap die Referenz.
Ich denke auch nicht, dass der Fehler so oft gemacht wird. Spätestens beim ersten Versuch, der auch fehlschlagen wird, weiß man, dass es so nicht geht. -
dennoch etwas tückisch... Re: Strings in switch vs. Stringvergleich
Autor: supersux 20.03.14 - 14:36
...sonst hätte ja schonmal jmd. darauf hingewiesen, dass das Beispiel falsch ist *scnr*
-
Re: Strings in switch vs. Stringvergleich
Autor: Nolan ra Sinjaria 20.03.14 - 16:42
monettenom schrieb:
--------------------------------------------------------------------------------
> if(value.equals("test"))
> ; // schon besser
aber noch nicht gut ;)
Ich habe nix gegen Christen. Ich habe nix gegen Moslems. Ich habe nix gegen Vegetarier. Ich habe nix gegen Apple-Fans. Aber ich habe etwas gegen Missionare... -
Re: Strings in switch vs. Stringvergleich
Autor: QDOS 20.03.14 - 17:21
Shore schrieb:
--------------------------------------------------------------------------------
> Ist das in anderen typisierten Programmiersprachen anders?
Ja bei allen bei denen Wertesemantik der Default ist - z.B: C++
std::string value = "test";
if (value == "test")
; // wird IMMER erreicht -
Re: Strings in switch vs. Stringvergleich
Autor: Themenzersetzer 20.03.14 - 21:54
Nolan ra Sinjaria schrieb:
--------------------------------------------------------------------------------
> monettenom schrieb:
> ---------------------------------------------------------------------------
> -----
> > if(value.equals("test"))
> > ; // schon besser
>
> aber noch nicht gut ;)
Was ist gut? -
Re: Strings in switch vs. Stringvergleich
Autor: keks.de 20.03.14 - 22:09
Themenzersetzer schrieb:
--------------------------------------------------------------------------------
> Nolan ra Sinjaria schrieb:
> ---------------------------------------------------------------------------
> -----
> > monettenom schrieb:
> >
> ---------------------------------------------------------------------------
>
> > -----
> > > if(value.equals("test"))
> > > ; // schon besser
> >
> > aber noch nicht gut ;)
>
> Was ist gut?
if ("test".equals(value))
oder auch (und um es zu verdeutlichen):
if (value != null && value.equals("test"))
LG, Keks -
Re: Strings in switch vs. Stringvergleich
Autor: QDOS 20.03.14 - 23:01
keks.de schrieb:
--------------------------------------------------------------------------------
> if ("test".equals(value))
>
> oder auch (und um es zu verdeutlichen):
>
> if (value != null && value.equals("test"))
Man wärs klasse, wenns eine Sprache gäbe, die garantiert, dass Referenzen niemals null sind… (Achja sowas gibt's seit den 80igern und wurde später schlecht kopiert…) -
Re: Strings in switch vs. Stringvergleich
Autor: MrGlass 20.03.14 - 23:39
Aua, aua, au!
> public class Main
> {
> public static void main(String[] args)
> {
> String value = "test";
> if (value == "test")
> {
> System.out.println("Wird nie erreicht!");
> }
> if (value.equals("test"))
> {
> System.out.println("Schon besser!");
> }
> }
> }
Du bist dir schon im Klaren darüber, dass die Ausgabe folgende ist, oder?
Wird nie erreicht!
Schon besser!
Du hast vielleicht das Richtige gemeint, aber so wie du es hingeschrieben hast, funktioniert der Operator == wunderbar für den Vergleich von value und "test". -
Re: Strings in switch vs. Stringvergleich
Autor: Nolan ra Sinjaria 21.03.14 - 08:39
QDOS schrieb:
--------------------------------------------------------------------------------
> Man wärs klasse, wenns eine Sprache gäbe, die garantiert, dass Referenzen
> niemals null sind… (Achja sowas gibt's seit den 80igern und wurde
> später schlecht kopiert…)
hör mir auf. Ich schimpf hier ständig rum, weil ich bei C# fast alle Basistypen erstmal extra als Nullable deklarieren muss, um sinnvoll mit der DB arbeiten zu können.
und null für "kein Wert vorhanden" ist immer besser als dafür -1 oder ähnliches festzulegen, was man gern auch mal vergisst.
Ich habe nix gegen Christen. Ich habe nix gegen Moslems. Ich habe nix gegen Vegetarier. Ich habe nix gegen Apple-Fans. Aber ich habe etwas gegen Missionare... -
Re: Strings in switch vs. Stringvergleich
Autor: TrudleR 21.03.14 - 09:43
monettenom schrieb:
--------------------------------------------------------------------------------
> Dass bei value == "test" kein Stringvergleich ist, ist nicht sehr intuitiv
> und wird häufig falsch gemacht. Dass nun Strings bei switch()-Anweisungen
> verwendet werden können, bei Vergleichen aber nicht, macht das nicht
> besser.
Also wie schon gesagt wurde, wird der Code des Threadstarters erreicht. Das funktioniert, aber das wurde meines Wissens erst später in Java implementiert und war nicht von Anfang an dabei.
Grund: Wenn ein String Objekt instanziert wird, schaut die JRE nach, ob es das Objekt schon gibt (String-Pool), wenn ja, wird einfach der Zeiger (Referenz) darauf gerichtet.
Da String NICHT verändert werden können (jegliche Änderungen an einem String führen zu einem neuen Objekt) ist das auch kein Problem. Dadurch wird die IF Anweisung des Threadstarters durchaus besucht.
Zur Switch-Anweisung: Dass man da Strings vergleichen kann, funktioniert erst seit Java 7. Ausserdem vergleicht man dort ja nicht mit dem == Operator, sondern schreibt einfach "case" hin, somit finde ich es schon nicht so gerechtfertigt wenn man sagt, die switch mache das genauso. :)
In C# kann man programmieren, dass sich die Klassen mit dem == Operator Vergleichen lassen (ob das bei Strings Standart ist, glaube ich nicht, aber da bin ich grade zu wenig sattelfest für eine klare Aussage). Allgemein muss ich aber sagen, dass C# in meinen Augen SEHR unlesbaren Code zulässt, was mir selber ziemlich widersteht. Die diversen Möglichkeiten, wie man ein und dasselbe programmieren kann (ich rede von den basicsten Basics :P) sind einfach viel zu breit gefächert. Man muss sich diese Sprache ziemlich verinnerlichen, bis man da mal fremden Code analysieren und eventuell weiterentwickeln kann. Sicher, wenn man selber was programmiert, kann man vielleicht Codezeilen an allen Ecken sparen und sich als super effizienten Programmierer fühlen, aber wehe dem, der diesen Code dann mal irgendwann ausgraben muss...
Die Lamda Ausdrücke in Java finde ich ja interessant. Die Vereinfachung der Getter- und Setter-Methoden in C# irgendwo ebenfalls. Aber fast alles andere finde ich dort schwerst überflüssig.
Gruss
Trudler -
Re: Strings in switch vs. Stringvergleich
Autor: supersux 21.03.14 - 10:47
TrudleR schrieb:
--------------------------------------------------------------------------------
> Also wie schon gesagt wurde, wird der Code des Threadstarters erreicht. Das
> funktioniert, aber das wurde meines Wissens erst später in Java
> implementiert und war nicht von Anfang an dabei.
erstmalig in 6 (und dort war der Pool noch im PermGen...)
> Grund: Wenn ein String Objekt instanziert wird, schaut die JRE nach, ob es
> das Objekt schon gibt (String-Pool), wenn ja, wird einfach der Zeiger
> (Referenz) darauf gerichtet.
nein, nur für Literals & Constant Expressions, ansonsten muss man selber .intern() aufrufen -
Re: Strings in switch vs. Stringvergleich
Autor: frostbitten king 21.03.14 - 11:21
Nolan ra Sinjaria schrieb:
--------------------------------------------------------------------------------
> QDOS schrieb:
> ---------------------------------------------------------------------------
> -----
> > Man wärs klasse, wenns eine Sprache gäbe, die garantiert, dass
> Referenzen
> > niemals null sind… (Achja sowas gibt's seit den 80igern und wurde
> > später schlecht kopiert…)
>
> hör mir auf. Ich schimpf hier ständig rum, weil ich bei C# fast alle
> Basistypen erstmal extra als Nullable deklarieren muss, um sinnvoll mit der
> DB arbeiten zu können.
Ummmmm, wie war das noch gleich damals im Studium. Immer 3te Normalform und ja keine Nullvalues -> Nallvalues.equals("evil") == true :D. -
Re: Strings in switch vs. Stringvergleich
Autor: Shore 21.03.14 - 12:19
Oder du nimmst einfach eine Konstante. Da hat man wenigstens nicht das Problem, dass der Code mit einer NullReferenceException abschmiert...
-
Re: Strings in switch vs. Stringvergleich
Autor: Shore 21.03.14 - 12:22
Oder zumindest, dass NULL Funktionen aufnehmen kann. Finde ich persönlich ja sehr angenehm in Objective-C.



