4Danke
ERLEDIGT
JA
JA
ANTWORTEN
8
8
ZUGRIFFE
341
341
EMPFEHLEN
-
17.03.10 12:12 #1
- Registriert seit
- Sep 2008
- Beiträge
- 78
Hallo,
ich habe ein Verständnisproblem bei dem Operator "==".
Wenn ich es richtig verstanden habe, wird bei Objekten mit den Operator "==" nicht der Inhalt, sondern die Reverenz (also der Speicherort) verglichen.
Zwei verschieden Objekte sollten daher immer "false" liefern, auch wenn deren Inhalt gleich ist. ==> Tut es aber nicht immer
Folgendes Beispielprogramm
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
public class MainProg { public static void main(String[] args) { Integer x = 1; Integer y = 1; Double e = 1.0; Double r = 1.0; Long c = 1l; Long v = 1l; Float u = 1.0f; Float i = 1.0f; System.out.println(x == y); System.out.println(x.equals(y)); System.out.println("------------"); System.out.println(e == r); System.out.println(e.equals(r)); System.out.println("------------"); System.out.println(c == v); System.out.println(c.equals(v)); System.out.println("------------"); System.out.println(u == i); System.out.println(u.equals(i)); } }
liefert folgende Ausgabe:
Code :1 2 3 4 5 6 7 8 9 10 11
true true ------------ false true ------------ true true ------------ false true
Müsste theoretisch nicht bei allen Vergleichen mit "==" ein "false" herauskommen.
Warum ist das nicht so?
MfG
hansmueller
-
17.03.10 12:18 #2
Bei dieser Variante kommt immer das heraus, was du erwartest:
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
public static void main(String[] args) { Integer x = new Integer(1); Integer y = new Integer(1); Double e = 1.0; Double r = 1.0; Long c = new Long(11); Long v = new Long(11); Float u = 1.0f; Float i = 1.0f; System.out.println(x == y); System.out.println(x.equals(y)); System.out.println("------------"); System.out.println(e == r); System.out.println(e.equals(r)); System.out.println("------------"); System.out.println(c == v); System.out.println(c.equals(v)); System.out.println("------------"); System.out.println(u == i); System.out.println(u.equals(i)); }
Bleibt zu klären wo der unterschied zwischen:
undCode java:1
Integer x = 1;
liegt.
Ich hätt eigentlich auch erwartet das in beiden Fällen eine eigene Instanz angelegt wird.
Außerdem warum verhält es sich bei Double und Float nicht so, sonder nur bei Integer und Long?
Fragen über Fragen, evtl. postet ja gleich noch jemand der mehr Ahnung hat als wir beiden.Wenn mein Beitrag dir geholfen hat, würde ich mich sehr über eine positive Bewertung oder ein Danke freuen
Gruß Johannes
::: Homepage :::
-
17.03.10 13:01 #3
Hab gerade mal noch ein wenig herumgetestet.
Wenn du eine Variable überdann vergleicht der == Operator den Inhalt der Variable.Code :1
Integer x = 1;
Wenn du über den über NEW instanzierst hast, vergleicht er die Instanzen.
Code java:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
package test; public class GleichGleich { public static void main(String[] args) { Integer a = new Integer(1); Integer b = new Integer(1); Integer c = 1; Integer d = 1; System.out.println("a und b"); vergleichen(a,b); System.out.println("c und d"); vergleichen(c,d); System.out.println("a und c"); vergleichen(a,c); System.out.println("b und d"); vergleichen(b,d); System.out.println("c und a"); vergleichen(c,a); System.out.println("d und b"); vergleichen(d,b); } public static void vergleichen(Integer x, Integer y) { // x hochzählen x += 1; // Inhalte ausgeben System.out.println(x+" == "+y+" : "+(x==y)); // x runterzählen x -= 1; // Inhalte ausgeben System.out.println(x+" == "+y+" : "+(x==y)); System.out.println(""); } }
Ausgabe:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
a und b 2 == 1 : false 1 == 1 : false c und d 2 == 1 : false 1 == 1 : true a und c 2 == 1 : false 1 == 1 : true b und d 2 == 1 : false 1 == 1 : true c und a 2 == 1 : false 1 == 1 : false d und b 2 == 1 : false 1 == 1 : false
Geändert von Johannes7146 (17.03.10 um 13:24 Uhr)
Wenn mein Beitrag dir geholfen hat, würde ich mich sehr über eine positive Bewertung oder ein Danke freuen
Gruß Johannes
::: Homepage :::
-
17.03.10 14:35 #4
- Registriert seit
- Sep 2008
- Beiträge
- 78
Schon sehr merkwürdig.
Bei Boolean hat man den gleichen Effekt.
liefertCode :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
public class MainProg { public static void main(String[] args) { Boolean j = true; Boolean k = true; Boolean n = new Boolean(true); Boolean m = new Boolean(true); System.out.println(j == k); System.out.println(j.equals(k)); System.out.println("------------"); System.out.println(n == m); System.out.println(n.equals(m)); } }
Code :1 2 3 4 5
true true ------------ false true
Vielleicht liegt es daran, daß es sich eigendlich um elemtare Typen handelt, welche nur von einer Wrapperklasse umgeben sind. Elementare Typen sind keine Klassen bzw. Objekte im eigendlichen Sinn, sondern stehen außerhalb des objektorientierten Konzepts von Java. (Ich hoffe, daß stimmt so, wie ich es geschrieben habe.)
Dieses inkonsequente Verhalten wird dadurch aber auch nicht geklärt.
Es wäre wirklich interessant zu wissen, ob dieses Verhalten gewollt ist und eine Logik dahintersteckt, oder ob es sich einfach um einen Bug handelt?
-
17.03.10 14:40 #5
Um noch eine Theorie in den Raum zu werfen:
Es gibt bei Strings einen Pool, in dem zuerst geschaut wird, ob bereits eine Instanze mit dem Wert existiert, und wenn ja, diese verwendet wird.
Falls man new verwendet wird das aber ignoriert, vielleicht ist es bei primitiven Typen genauso.Mein kleiner webstart Projektplaner:
http://178.77.101.236/ppws/
Ideen, Verbesserungsvorschläge, Bugsmeldungen und allg. Kritik erwünscht und erbeten.
Danke. :)
-
17.03.10 15:03 #6
- Registriert seit
- Sep 2008
- Beiträge
- 78
Die Erklärung hört sich gut an und könnte ein Schritt in die richtige Richtung sein.
ergibtCode :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
public class MainProg { public static void main(String[] args) { String x = "Hallo"; String y = "Hallo"; String e = new String("Hallo"); String r = new String("Hallo"); System.out.println(x == y); System.out.println(x.equals(y)); System.out.println("------------"); System.out.println(e == r); System.out.println(e.equals(r)); } }
Code :1 2 3 4 5
true true ------------ false true
Es bleiben aber noch viele Fragen offen.
Warum gibt es für Gleitkomma-Typen keinen solchen Pool?
Und warum das unterschiedliche Verhalten bei den verschiedenen Arten der Instanziierung? (Einmal mit "new", einmal ohne.)
-
17.03.10 15:41 #7
- Registriert seit
- Sep 2008
- Beiträge
- 78
Bezüglich der Sache mit dem String-Pool habe ich folgendes im Netz gefunden:
http://www.javaschubla.de/2007/javaerst0150.html
http://www.java-blog-buch.de/0302-strings-vergleichen/
Kann wirklich sein, das es für boolean- und Integer-Typen auch einen solchen Pool gibt.
Warum dann aber nicht für Gleitkomma-Typen?
-
Moin,
also das ursprüngliche Problem hat mit den Pools so direkt erst mal gar nix zu tun. Grundlage für das Verhalten sind die Konventionen für das Autoboxing. Dabei werden laut Sprachspezifikation bestimmte Werte in identische Objekte umgewandelt. Garantiert wird das für die beiden boolean, alle byte, chars von \u0000 to \u007f sowie int und short von -128 bis 127. Für alle anderen Werte wird es nicht garantiert aber der Abschnitt in der Spec enthält noch die Anmerkung, dass im Idealfall alle Werte auf das gleiche Objekt zeigen sollten - was zumindest für long auch geht (aber auch dort nur im Bereich -128 bis 127).
Wenn man Vergleiche außerhalb der von der Spec garantierten Bereiche durchführt (z.B. Integer 512) kann true rauskommen, muss aber nicht (zumindest bei meiner Sun VM tut es das nicht). Im Endeffekt sollten Objekte immer mit equals() verglichen werden, wenn es um die Gleichheit geht, ohne irgendwelche Vermutungen anzustellen ob die Dinger nun identisch sind oder nicht.
Und die Pools sind wieder eine andere Geschichte. Tatsächlich gibt es einen "klassenübergreifenden Pool" nur für Stringliterale (alles zwischen " ") - alle anderen Konstanten befinden sich in einen Pool pro Klasse. Über den Stringpool werden gleiche Stringliterale in den Klassen kanonisiert -> gleiche Werte werden durch ein identisches Objekt repräsentiert. Man kann auch zur Laufzeit erzeugte Strings mittels der intern() Methode kanonisieren. Diese schaut, ob es im Pool bereits ein gleicher (equals) String enthalten ist. Wenn ja liefert sie eine Referenz auf diesen String zurück. Wenn nein, wird ein gleichartiger String im Pool aufgenommen und eine Referenz auf diesen zurückgeliefert. Das Problem bei intern() ist, dass nicht spezifiziert ist, was passiert, wenn der String-Pool "voll läuft". Einige VM's steigen dann wohl mit einer OutOfMemory Exception aus. Die aktuellen Sun-VM's verwalten den Pool in einem speziellen Speicherbereich, der Permanent Generation auf dem auch eine Garbage Collection stattfindet - dadurch werden Einträge des Stringpool, die nirgends mehr verwendet werden entsprechend entfernt.For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references.
hth
THMDIf Java had true garbage collection, most programs would delete themselves upon execution. (Robert Sewell)
-
19.03.10 09:44 #9
- Registriert seit
- Sep 2008
- Beiträge
- 78
Danke THMD,
das bringt Licht ins Dunkle.
Für die, die es Interessiert habe ich noch folgende Links bezüglich Autoboxing gefunden:
http://openbook.galileodesign.de/jav..._001.htm#t2t36
http://www.java-blog-buch.de/0607-autoboxing/
MfG
hansmueller
Ähnliche Themen
-
AutoIt "Ist nicht gleich" Operator gesucht
Von YannikTold im Forum Sonstige SprachenAntworten: 4Letzter Beitrag: 15.01.11, 11:00 -
Richtige Syntax bei Operatorüberladung, wann sind "friend", "const", "&" nötig?
Von mrs_schokokeks im Forum C/C++Antworten: 4Letzter Beitrag: 25.08.10, 19:13 -
Wie benutze ich "operator Funktion()"?
Von Jennesta im Forum C/C++Antworten: 3Letzter Beitrag: 13.06.10, 14:16 -
Seltsamer Fehler: "Fatal error: [] operator not supported for strings"
Von sluggish im Forum PHPAntworten: 6Letzter Beitrag: 02.05.09, 18:11 -
Operator "AND" und Probleme bei Abfrage
Von Tservarius im Forum PHPAntworten: 1Letzter Beitrag: 17.10.04, 21:49





Zitieren
Login





