Java stellt seit der Version 5.0 einen Mechanismus bereit, der diese
Verfahren automatisch erledigt (Autoboxing), sodass die folgenden
Formulierungen möglich sind:
Hier geschieht das Folgende: ein Objekt der Wrapper-Klasse
Integer
wird durch Übergabe des Wertes 5 an den Konstruktor gebildet. Der
primitive Typ
n wird darauf hin mit diesem Objekt initialisiert,
indem zunächst ein automatisches Unboxing des Referenztyps stattfindet.
Es liegt also eine Wandlung des Referenztyps
i in den primitiven
Typ vor, ohne dass ein explizites Casting vorgenommen oder ein Unboxing
formuliert werden müsste. Im dritten Schritt wird der umgekehrte Weg
gezeigt: Der primitive
int-Typ wird ohne Casting durch
Boxing
in dem Referenztyp der Wrapper-Klasse
Integer erneut gekapselt.
Man muss sich darüber im Klaren sein, dass in jedem Fall
Boxing-
und
Unboxingvorgänge im Hintergrund ablaufen. Insbesondere
für rechenintensive und/oder zeitkritische Anwendungen wird es somit
nicht empfohlen.
Eine weitere tückische Eigenheit zeigt sich z.B.
in den folgenden Codebeispielen und soll verdeutlichen, dass - wie Java
empfiehlt - alle (Un)Boxing-Vorgänge nur durchgeführt werden
sollten, wenn unbedingt notwendig:
Integer m = 1500;
Integer n = 1500;
System.out.println(m == n);
// false
Hier werden durch Boxing zwei
Integer-Objekte gebildet, deren
Vergleich deshalb
false ergibt, weil es sich um zwei
unterschiedliche Objekte mit entsprechend verschiedenen Speicherplätzen
handelt.
Integer i = 15;
Integer j = 15;
System.out.println(i == j); //
true
Erstaunlicherweise erzeugt hier der Vergleich zweier wie im vorhergehenden
Beispiel gebildeter Wrapper-Objekte
false als Ergebnis. Wie ist das
zu erklären?
Die Lösung liegt darin, dass Java bei Werten
innerhalb des Byte-Wertebereiches (-128 bis 127) bei Übereinstimmung
neu gebildete Wrapper-Objekte mit bereits vorhandenen besetzt, der Vergleich
hier somit auf ein und die selbe Speicherstelle zeigt. Man spricht von einem
Pool. Dieses Prinzip gilt für alle ganzzahligen numerischen
Wrapper-Datentypen inclusive
Character, nicht jedoch für die
Fließkomma-Wrapper.
Integer k = new Integer(15);
Integer l = new Integer(15);
System.out.println(k == l); // false
Dies Beispiel greift das vorletzte auf und demonstriert, dass die Verwendung
des angesprochenen Objekt-Pools nur dann gilt, wenn die Wrapper-Objekte
nicht mit
new gebildet wurden. In diesem Fall wird durch
new
den neu gebildeten Objekten zwangsläufig jeweils neuer Speicherplatz
zugewiesen.