Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes.
Converting an object of a wrapper type (e.g. Integer) to its corresponding primitive (e.g. int) value is called unboxing.
The following table lists the primitive types and their corresponding wrapper classes, which are used by the Java compiler for autoboxing and unboxing:
Primitive Type |
Wrapper Class |
boolean
|
java.lang.Boolean
|
byte
|
java.lang.Byte
|
char
|
java.lang.Character
|
float
|
java.lang.Float
|
int
|
java.lang.Integer
|
long
|
java.lang.Long
|
short
|
java.lang.Short
|
double
|
java.lang.Double
|
Autoboxing is just syntactic sugar which is replaced by corresponding wrapper class by using static methods like Integer.valueOf(int i) , Long.valueOf(long l) etc.
Unboxing is just syntactic sugar which is replaced by corresponding primitive by using instance methods like Integer.intValue() , Long.longValue() etc.
Examples
package com.logicbig.example;
public class AutoboxingAndUnboxing {
public static void main(String[] args) {
int pInt = 5;
//autoboxing
Integer wInt = pInt;
//unboxing
int pInt2 = wInt;
}
}
Let's compile above class and analyze byte code with javap command
$ javap -c AutoboxingAndUnboxing.class
Compiled from "AutoboxingAndUnboxing.java"
public class com.logicbig.example.AutoboxingAndUnboxing {
public com.logicbig.example.AutoboxingAndUnboxing();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."
":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_5
1: istore_1
2: iload_1
3: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
6: astore_2
7: aload_2
8: invokevirtual #3 // Method java/lang/Integer.intValue:()I
11: istore_3
12: return
}
As seen above compiler uses method Integer.valueOf() for autoboxing and method Integer.intValue() for unboxing.
Let's use above two methods directly:
package com.logicbig.example;
public class AutoboxingAndUnboxing2 {
public static void main(String[] args) {
int pInt = 5;
//to wrapper
Integer wInt = Integer.valueOf(pInt);
//to primitive
int pInt2 = wInt.intValue();
}
}
Let's compile above class and use javap command to analyze the byte codes.
$ javap -c AutoboxingAndUnboxing2.class
Compiled from "AutoboxingAndUnboxing2.java"
public class com.logicbig.example.AutoboxingAndUnboxing2 {
public com.logicbig.example.AutoboxingAndUnboxing2();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."
":()V
4: return
public static void main(java.lang.String[]);
Code:
0: iconst_5
1: istore_1
2: iload_1
3: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
6: astore_2
7: aload_2
8: invokevirtual #3 // Method java/lang/Integer.intValue:()I
11: istore_3
12: return
}
As seen above there's no difference between complied code of the last example and of the above example.
Unboxing and NullPointerException
During unboxing if wrapper type is null, the conversion throws a NullPointerException
package com.logicbig.example;
public class UnboxingWithNPE {
public static void main(String[] args) {
Integer wInt = null;
int pInt = wInt.intValue();
System.out.println(pInt);
}
}
Exception in thread "main" java.lang.NullPointerException at com.logicbig.example.UnboxingWithNPE.main(UnboxingWithNPE.java:6)
The reason of above exception is that the Integer value is null in the replaced code Integer.intValue()
Fixing NullPointerException with Unboxing
Checking for null using ternary operator
To fix above exception we can use ternary operator to check possible null value of the wrapper:
public class UnboxingWithNPEFix {
public static void main(String[] args) {
Integer wInt = null;
int pInt = wInt != null ? wInt : 0;
System.out.println(pInt);
}
} 0
Using Java 8 Optional
We can also use Java 8 java.util.Optional:
package com.logicbig.example;
import java.util.Optional;
public class UnboxingWithNPEFix2 {
public static void main(String[] args) {
Integer wInt = null;
int i = Optional.ofNullable(wInt).orElse(0);
System.out.println(i);
}
}
0
Using a generic utility method
We can also create a generic utility method to convert nullable wrapper to not-nullable wrapper first:
package com.logicbig.example;
import java.util.Objects;
public class UnboxingWithNPEFix3 {
public static void main(String[] args) {
Integer wInt = null;
int i = toNotNullable(wInt, 0);
System.out.println(i);
Double wDouble = null;
double d = toNotNullable(wDouble, 0.0d);
System.out.println(d);
}
public static <T> T toNotNullable(T object, T defaultValue) {
Objects.requireNonNull(defaultValue, "The default value cannot be null");
return object == null ? defaultValue : object;
}
}
0 0.0
Using Objects methods (Java 9)
Or alternatively we can use one of the following methods of java.util.Objects (available since Java 9):
public static <T> T requireNonNullElse(T obj, T defaultObj)
Returns the first argument if it is non-null or otherwise returns the non-null second argument.
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier)
Returns the first argument if it is non-null or otherwise returns the non-null value of supplier.get().
package com.logicbig.example;
import java.util.Objects;
public class UnboxingWithNPEFix4 {
public static void main(String[] args) {
Integer wInt = null;
int i = Objects.requireNonNullElse(wInt, 0);
System.out.println(i);
Double wDouble = null;
double d = Objects.requireNonNullElseGet(wDouble, () -> 0.0d);
System.out.println(d);
}
}
0 0.0
Example ProjectDependencies and Technologies Used:
|