Autoboxing und Unboxing sind Verfahren zum automatischen 'Ein-' und 'Auspacken' von primitiven Datentypen in Referenztypen. v.5.0
Java stellt seit der Version 5.0 einen Mechanismus bereit, der diese Verfahren automatisch erledigt (Autoboxing), sodass die folgenden Formulierungen möglich sind:
Integer i = new Integer(5);
int n = i;
Integer j = n;
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 true 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.