AutoBoxing Kritik auf wikipedia - Frage

Sonecc

Gesperrter Benutzer
Beim stöbern traf ich grade auf folgenden Wikipedia beitrag Criticism of Java - Wikipedia, the free encyclopedia

Ich war doch arg überrascht, als ich beim autoboxing teil ankam und den dortigen Code ausprobiert habe.

Siehe hier:
Java:
		Integer a = 2;
		Integer b = 2;
		Integer c = 2000;
		Integer d = 2000;
		 
		if ( a == b ) {  
			System.out.println("a == b");
		}

		if ( c == d ) {  
			System.out.println("c == d");
		}

Ausgabe ist:

Code:
a == b


Wie kommt das?
 

Michael...

Top Contributor
Interessant, wundert mich schon, dass a == b true liefert, da es sich ja eigentlich um zwei verschiedene Objekte handelt.
Würde sagen: Fehlerhafte Implementierung des AutoBoxing ;-)
 

tfa

Top Contributor
Das ist kein Bug. Für ints zwischen -128 und 127 gibt es einen Cache in java.lang.Integer, der auch vom Autoboxing verwendet wird. Sucht mal im Java-Quiz-Thread, da gab es vor langer Zeit mal eine Frage dazu.
Wenn man Objekte immer schön mit equals vergleicht, ist diese "Unschönheit" kein Problem.
 

ThreadPool

Bekanntes Mitglied
Das Verhalten ist korrekt. Wenn man den Inhalt zweier Wrapper miteinander vergleichen möchte nimmt man die equals Methode andernfalls wir ja verglichen ob es sich um die selben Objekte handelt. Der Grund weshalb für die kleinen Zahlen herauskommt das es sich um das selbe Objekt handelt liegt darin begründet das versucht wird Speicherplatz zu sparen. Wrapperobjekte wie Integer werden als identisch behandelt wenn ihr primitiver Wert im Bereich -128 - 127 liegt. Ähnliches Verhalten gibt es bei Short, Boolean, Byte und Character.
 

Sonecc

Gesperrter Benutzer
Mit anderen Worten, ist es kein Bug sondern ein Feature :D

Dass equals ein richtiges Ergebnis liefert ist übrigens klar, aber für das Beispiel ja irrelevant.
Deine Aussage (die schlüssig ist) zeigt jedenfalls, dass die Aussage in dem Wikipedia beitrag so nicht ganz richtig ist, weil einige Umstände nicht beachtet werden (z.B. das Integer eben Objekte sind ... )
 

nrg

Top Contributor
Würde mal sagen das ist das gleiche wie mit Stringliteralen...

explizite Objekterzeugung:
String a = new String("abc");
String b = new String("abc");
(a == b) liefert false

Gebräuchliche Erzeugung mit Stringliteralen:
String a = "abc";
String b = "abc";
(a == b) liefert true.

Nur, dass die Wrapperklassen da anscheinend einen Wertebereich haben. Edit: warum das so ist leutet mir allerdings gerade nicht ganz ein.....

Grüße
andi
 
Zuletzt bearbeitet:

musiKk

Top Contributor
Bei Strings hat das einen anderen Grund. Stringliterale werden automatisch interniert und teilen sich daher eine Instanz. Man kann das auch manuell über [c]String#intern()[/c] auslösen. Das ist in der JLS definiert.

Die Klasse [c]Integer[/c] hingegen legt diesen Cache statisch an. Das ist aber völlig transparent; das Intervall hätte auch größer oder kleiner sein können (zumindest habe ich in der JLS keine gegenteilige Aussage gefunden).
 
S

SlaterB

Gast
. Man kann das auch manuell über [c]String#intern()[/c] auslösen.
nur bringt das wenig, denn wenn man es an einem String aufruft, ist das neue String-Objekt ja schon da, oder? ;)
würde sich höchstens auf einen == Vergleich auswirken, aber was bringt das schon

der Sinn eines Caches ist ja eher, Speicher/ Zeit zu sparen

edit:
ah, wenn man sie längerfristig speichern muss, dann bringt es ein bisschen,
wenn von 100.000 Strings 30.000 gleich sind, bleiben nur 70.000 im Speicher zu halten, der Rest kann bald wieder freigegeben werden
 
Zuletzt bearbeitet von einem Moderator:

Ähnliche Java Themen


Oben