Advanced Java Services | Autoboxing |
Autoboxing nennt man das automatische Umwandeln von primitiven Datentypen
in Hüllklassenäquivalente durch den Compiler, d.h. der Compiler ersetzt etwa
das Literal 17 durch new Integer(17) falls es notwendig ist. Ebenso gibt es
ab 1.5 Auto-unboxing, also das automatische Umwandeln von Hüllklassenobjekten in
primitive Datentypen.
Autoboxing ist, mit Verlaub, ein gefährliches Feature, weil es den eigentlichen Vorgang
verschleiert. In der Vorstellung der neuen 1.5 Features schreibt Sun:
So when should you use autoboxing and unboxing?
Use them only when there is an "impedance mismatch" between reference types and primitives,
for example, when you have to put numerical values into a collection. It is not appropriate
to use autoboxing and unboxing for scientific computing, or other performance-sensitive
numerical code.
und weiter:
An Integer is not a substitute for an int; autoboxing and unboxing blur the distinction between primitive types and reference types, but they do not eliminate it.
Farbliche Hervorhebungen durch den Autor.
int i = 17; Integer in1 = i ; // autoboxing Integer in2 = 71 ; // autoboxing // Erzeugen eines Hüllklassenobjektes bis 1.4 Integer in = new Integer(i) ; // ab 1.5 mit autoboxing Integer in2 = i ; // entspricht new Integer(i); // Erzeugen eines Hüllklassenobjektes aus einem String Integer in3 = new Integer("17") ; // das geht auch in 1.5 nicht (incompatible types) //Integer in4 = "17" ;
Wir betrachten die Ausdrücke mit den Operatoren
++ , -- , +
(unäres plus),
-
(unäres minus),
~
(1-komplement)
public class AutoBoxing1 { public static void main(String args[]) { int i = 17, j = 18, k; Integer in1 = i ; // Integer in1 = Integer.valueOf(i); Integer in2 = j ; // Integer in2 = Integer.valueOf(j); in1++ ; // in1 = Integer.valueOf(in1.intValue() + 1); --in2 ; // in2 = Integer.valueOf(in2.intValue() - 1); k = -in1; // int k = -in1.intValue(); in2 = +in1; // in2 = Integer.valueOf(in1.intValue()); in1 = ~in2 ; // in1 = Integer.valueOf(~in2.intValue()); } }
Im Kommentar hinter den statements steht jeweils, wie der compiler unseren code übersetzt.
Wir betrachten die Ausdrücke mit den Operatoren
< , > , <=, >= , == , !=
public class AutoBoxing2 { public static void main(String args[]) { int i = 17, j = 18, k; Integer in1 = i ; // Integer in1 = Integer.valueOf(i); Integer in2 = j ; // Integer in2 = Integer.valueOf(j); if( i <= in2 ) // i <= in2.intValue() System.out.println(i + " <= " + in2); else System.out.println(i + " > " + in2); if( in1 >= j ) // in1.intValue() >= j System.out.println(in1 + " >= " + j); else System.out.println(in1 + " < " + j); if( in1 < in2 ) // in1.intValue() < in2.intValue() System.out.println(in1 + " < " + in2); else System.out.println(in1 + " >= " + in2); if( in1 == j ) // in1.intValue() == j System.out.println(in1 + " == " + j); else System.out.println(in1 + " != " + j); if( in1 == in2 ) // zeigervergleich, kein unboxing ! System.out.println(in1 + " == " + in2); else System.out.println(in1 + " != " + in2); in2 = in1 ; // referenzzuweisung if( in1 == in2 ) // zeigervergleich, kein unboxing ! System.out.println(in1 + " == " + in2); else System.out.println(in1 + " != " + in2); if( in1.equals(in2) ) System.out.println(in1 + " equals " + in2); else System.out.println(in1 + " not equal " + in2); in2 = new Integer(in1) ; // in2 = new Integer(in1.intValue()); neue referenz wird erstellt if( in1 == in2 ) // zeigervergleich, kein unboxing ! System.out.println(in1 + " == " + in2); else System.out.println(in1 + " != " + in2); if( in1.equals(in2) ) System.out.println(in1 + " equals " + in2); else System.out.println(in1 + " not equal " + in2); // System.out.println((new StringBuilder()).append(in1).append(" not equal ").append(in2).toString()); } }