Autoboxing and Unboxing data types in Java 5
Since Java 5, Java compilers can automatically convert between the primitive data types and their corresponding wrapper classes. This feature is called Autoboxing. For example, an int value can be automatically converted to a java.lang.Integer object. An object of a wrapper class can also be automatically converted to a primitive type. This is known as Unboxing.
Autoboxing and Unboxing feature lets programmers write cleaner code that is easier to understand and maintain.
The importance of Wrapper classes
Java is an Object-Oriented Programming Language. Conceptually, the primitive data types (byte, short, int, long, float, double, char and boolean) are not really objects. The Wrapper classes provide a way to represent these primitive data types as objects in Java. The corresponding wrapper classes for these primitive types are shown in the table below:
Primitive Type | Wrapper Class |
---|---|
boolean | java.lang.Boolean |
char | java.lang.Character |
byte | java.lang.Byte |
short | java.lang.Short |
int | java.lang.Integer |
long | java.lang.Long |
float | java.lang.Float |
double | java.lang.Double |
The wrapper classes become important in the case of generics. Few very common examples are when we need to deal with Collections, Serialization, Synchronization, etc.
List<Integer> li = new ArrayList<Integer>(); for (int i = 1; i < 50; i += 2) { li.add(i); // Autoboxing primitive int type to java.lang.Integer. }
The above code makes use of the autoboxing feature to handle an array of integers.
Autoboxing and Unboxing Examples
The following shows how primitive data types can be wrapped using the normal constructor method. The second part shows how these variables are automatically converted from primitive data types to wrapper classes.
// Example of Autoboxing // in Java 5.0 class AutoboxingExamples { public static void main(String[] args) { // primitive data types byte primitiveByte = 1; int primitiveInt = 10; float primitiveFloat = 18.6f; double primitiveDouble = 250.5; char primitiveChar = 'a'; // Simple wrapped object example. Byte wrappedByte = new Byte(primitiveByte); Integer wrappedInteger = new Integer(primitiveInt); Float wrappedFloat = new Float(primitiveFloat); Double wrappedDouble = new Double(primitiveDouble); Character wrappedChar = new Character(primitiveChar); // Autoboxing Examples Byte autoboxingByte = primitiveByte; Integer autoboxingInteger = primitiveInt; Float autoboxingFloat = primitiveFloat; Double autoboxingDouble = primitiveDouble; Character autoboxingChar = primitiveChar; } }
The following code shows how wrapped classes can automatically be converted to primitive datatypes through the unboxing feature.
// Example of Unboxing // in Java 5.0 public class UnboxingExamples { public static void main(String[] args) { // Creating objects using wrapper classes and autoboxing Byte autoboxingByte = 1; Integer autoboxingInteger = 10; Float autoboxingFloat = 18.6f; Double autoboxingDouble = 250.5; Character autoboxingChar = 'a'; // Unboxing to primitive data types. byte primitiveByte = autoboxingByte; int primitiveInt = autoboxingInteger; float primitiveFloat = autoboxingFloat; double primitiveDouble = autoboxingDouble; char primitiveChar = autoboxingChar; } }
Let us take the array list example:
List<Integer> integerList = new ArrayList<Integer>(); for (int i = 0; i < 10; i++) { integerList.add(i); } System.out.println(integerList.size());
This code does not generate a compile-time error even if you are adding a primitive int type value into the integerList that expects a value of type java.lang.Integer. This is because the code automatically converts the primitive type into the wrapper class. Effectively, the compiler converts the previous code to the following at runtime:
List<Integer> li = new ArrayList<Integer>(); for (int i = 1; i < 50; i += 2){ li.add(Integer.valueOf(i)); // <- Replacing i with Integer.valueOf(i). } System.out.println(integerList.size());
Java autoboxing and unboxing rules
The Java compiler converts a primitive type to wrapper class in the following scenarios:
- A primitive type is passed as a parameter to a method that expects the corresponding wrapper class object
- A primitive type is assigned to a variable that has the type of the corresponding wrapper class.
The Java compiler converts a wrapper class object to the corresponding primitive type automatically in the following scenarios:
- An object of wrapped class type is passed as a parameter to a method that expects the corresponding primitive data type.
- An object of wrapped class type is assigned to a variable that has the type of the corresponding primitive data type.
For more examples visit Github Reository.