Since JDK 5.0, auto boxing/unboxing was introduced in Java. The trick is simple and helpful, but when I started testing different conversions between wrapper classes and primitive types, I get really confused how the concept of auto boxing works in Java. For example:
Boxing
int intValue = 0;
Integer intObject = intValue;
byte byteValue = 0;
intObject = byteValue; // ==> Error
After trying different cases (short
, long
, float
, double
), the only case which is accepted by the compiler is when the type of the value on the right of affectation operator is int
.
When I looked inside the source of Integer.class
I found that it implements only one constructor with int
parameter.
So my conclusion is that the concept of auto boxing is based on constructor implemented in the wrapper class. I want to know if this conclusion is true or there is another concept used by auto boxing?
Unboxing
Integer intObject = new Integer(0);
byte byteValue = intObject; // ==> Error (the same Error with short)
int intValue = intObject;
double doubleValue = intObject;
My conclusion about unboxing is that the wrapper class gives the value wrapped by the object in the corresponding type (Integer
==> int
), then the compiler use the usual rules of converting primitive types (byte
=> short
=> int
=> long
=> float
=> double
).
I want to know if this conclusion is true or there is another concept used by auto unboxing?
Advantage of Autoboxing and Unboxing in Java A Java programmer does not need to explicitly or manually write the code to convert primitive data to the wrapper class object and vice versa. Java compiler automatically performs autoboxing and unboxing as and when needed.
Autoboxing: Automatic conversion of primitive types to the object of their corresponding wrapper classes is known as autoboxing. For example – conversion of int to Integer, long to Long, double to Double etc. Unboxing: It is just the reverse process of autoboxing.
Autoboxing and unboxing lets developers write cleaner code, making it easier to read. The technique lets us use primitive types and Wrapper class objects interchangeably and we do not need to perform any typecasting explicitly.
Autoboxing and unboxing are introduced in Java 1.5 to automatically convert the primitive type into boxed primitive( Object or Wrapper class).
When in doubt, check the bytecode:
Integer n = 42;
becomes:
0: bipush 42
2: invokestatic #16 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
So in actuality, valueOf()
is used as opposed to the constructor (and the same goes for the other wrapper classes). This is beneficial since it allows for caching, and doesn't force the creation of a new object on each boxing operation.
The reverse is the following:
int n = Integer.valueOf(42);
which becomes:
0: bipush 42
2: invokestatic #16 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: invokevirtual #22 // Method java/lang/Integer.intValue:()I
8: istore_1
i.e. intValue()
is used (again, it's analogous for the other wrapper types as well). This is really all auto(un)boxing boils down to.
You can read about boxing and unboxing conversions in JLS §5.1.7 and JLS §5.1.8, respectively.
This confusion can be cleared by using a switch of javac -XD-printflat which is very helpful in cases such as this one. So to unravel the mystery of boxing and unboxing you can write a simple program like following :
import java.util.*;
public class Boxing{
public static void main(String[] args){
Double d1 = 10.123;
Float f1 = 12.12f;
Long l1 = 1234L;
Integer i1 = 55555;
Short s1 = 2345;
Byte b1 = 89;
double d2 = d1;
float f2 = f1;
long l2 = l1;
int i2 = i1;
short s2 = s1;
byte b2 = b1;
}
}
and now we compile the above file as:
javac -XD-printflat -d src/ Boxing.java
output of this command is a java file with all the syntactic sugar (Generic types, enhanced for loop and in this case boxing-unboxing etc) removed. following is the output
import java.util.*;
public class Boxing {
public Boxing() {
super();
}
public static void main(String[] args) {
Double d1 = Double.valueOf(10.123);
Float f1 = Float.valueOf(12.12F);
Long l1 = Long.valueOf(1234L);
Integer i1 = Integer.valueOf(55555);
Short s1 = Short.valueOf(2345);
Byte b1 = Byte.valueOf(89);
double d2 = d1.doubleValue();
float f2 = f1.floatValue();
long l2 = l1.longValue();
int i2 = i1.intValue();
short s2 = s1.shortValue();
byte b2 = b1.byteValue();
}
}
this is how java does boxing unboxing. using valueOf and ***Value methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With