The automatic conversion of primitive data types into its equivalent Wrapper type is known as boxing and opposite operation is known as unboxing.
Autoboxing and Unboxing with method overloading
In method overloading, boxing and unboxing can be performed. There are some rules for method overloading with boxing:
Widening beats boxing
Widening beats varargs
Boxing beats varargs
Widening beats boxing
class Boxing1{
static void m(int i){System.out.println("int");}
static void m(Integer i){System.out.println("Integer");}
public static void main(String args[]){
short s=30;
m(s);
}
}
Output:int
Widening beats varargs
class Boxing2{
static void m(int i, int i2){System.out.println("int int");}
static void m(Integer... i){System.out.println("Integer...");}
public static void main(String args[]){
short s1=30,s2=40;
m(s1,s2);
}
}
Output:int int
Boxing beats varargs
class Boxing3{
static void m(Integer i){System.out.println("Integer");}
static void m(Integer... i){System.out.println("Integer...");}
public static void main(String args[]){
int a=30;
m(a);
}
}
Output:Integer
Method overloading with Widening and Boxing
class Boxing4{
static void m(Long l){System.out.println("Long");}
public static void main(String args[]){
int a=30;
m(a);
}
}
Output:Compile Time Error
Compiler uses valueOf() method to convert primitive to Object and uses intValue(), doubleValue() etc to get primitive value from Object.
Read more: https://javarevisited.blogspot.com/2012/07/auto-boxing-and-unboxing-in-java-be.html#ixzz60pL8Qd1X
Unnecessary Object creation due to Autoboxing in Java
One of the dangers of autoboxing is throw away object which gets created if autoboxing occurs in a loop. Here is an example of how unnecessary object can slow down your application :
Integer sum = 0;
for(int i=1000; i<5000; i++){
sum+=i;
}
In this code sum+=i will expand as sum = sum + i and since + operator is not applicable to Integer object it will trigger unboxing of sum Integer object and then autoboxing of result which will be stored in sum which is Integer as shown below :
sum = sum.intValue() + i;
Integer sum = new Integer(result);
here since the sum is Integer, it will create around 4000 unnecessary Integer object which are just throw away and if this happens on a large scale has It potential to slow down system with frequent GC for arithmetic calculation always prefer primitive over boxed primitive and look for unintentional autoboxing in Java
There is another problem as well when you compare int variable to Integer object using == operator, the Integer object is converted to a primitive value. This can throw null pointer exception if the Integer object is null, which can crash your program.
Comparing Integer object with == in Java
Why you should not compare Integer using == in Java 5Some of the JVM cache objects of some wrapper class e.g. Integer from -128 to 127 and return same object which if compare via “ ==” can return true but after this range this validity doesn't work and to make it worse this behavior is JVM dependent so better avoid this kind of check and use equals() method. e.g.
Integer i1 = 260;
Integer i2 = 260;
if (i1 == i2) {
System.out.println("i1 and i2 is equal");
} else {
System.out.println("i1 and i2 is not equal ");
}
Here you will most probably get "i1 and i2 is not equal " at least in my machine.
because in this case, unboxing operation is not involved. The literal 260 is boxed into two different Integer objects ( again it varies between JVM to JVM) , and then those objects are compared with ==. The result is false, as the two objects are different instances, with different memory addresses. Because both sides of the == expression contain objects, no unboxing occurs.
Integer i1 = 100;
Integer i2 = 100;
if (i1 == i2) {
System.out.println("i1 and i2 is equal");
} else {
System.out.println("i1 and i2 is not equal ");
}
Here, most probably you will get the text "i1 and i2 is equal".
Because int values from -127 to 127 are in a range which most JVM will like to cache so the VM actually uses the same object instance (and therefore memory address) for both i1 and i2. As a result, == returns a true result.
This is very indeterministic and only shown by example since some JVM do optimization at certain integer value and try to return same object every time but its not guaranteed or written behavior.
So best is to avoid this kind of code in post Java 1.5 and instead use equals() method to compare Integers in Java, which is more deterministic and correct.
Autoboxing and Unboxing with method overloading
In method overloading, boxing and unboxing can be performed. There are some rules for method overloading with boxing:
Widening beats boxing
Widening beats varargs
Boxing beats varargs
Widening beats boxing
class Boxing1{
static void m(int i){System.out.println("int");}
static void m(Integer i){System.out.println("Integer");}
public static void main(String args[]){
short s=30;
m(s);
}
}
Output:int
Widening beats varargs
class Boxing2{
static void m(int i, int i2){System.out.println("int int");}
static void m(Integer... i){System.out.println("Integer...");}
public static void main(String args[]){
short s1=30,s2=40;
m(s1,s2);
}
}
Output:int int
Boxing beats varargs
class Boxing3{
static void m(Integer i){System.out.println("Integer");}
static void m(Integer... i){System.out.println("Integer...");}
public static void main(String args[]){
int a=30;
m(a);
}
}
Output:Integer
Method overloading with Widening and Boxing
class Boxing4{
static void m(Long l){System.out.println("Long");}
public static void main(String args[]){
int a=30;
m(a);
}
}
Output:Compile Time Error
Compiler uses valueOf() method to convert primitive to Object and uses intValue(), doubleValue() etc to get primitive value from Object.
Read more: https://javarevisited.blogspot.com/2012/07/auto-boxing-and-unboxing-in-java-be.html#ixzz60pL8Qd1X
Unnecessary Object creation due to Autoboxing in Java
One of the dangers of autoboxing is throw away object which gets created if autoboxing occurs in a loop. Here is an example of how unnecessary object can slow down your application :
Integer sum = 0;
for(int i=1000; i<5000; i++){
sum+=i;
}
In this code sum+=i will expand as sum = sum + i and since + operator is not applicable to Integer object it will trigger unboxing of sum Integer object and then autoboxing of result which will be stored in sum which is Integer as shown below :
sum = sum.intValue() + i;
Integer sum = new Integer(result);
here since the sum is Integer, it will create around 4000 unnecessary Integer object which are just throw away and if this happens on a large scale has It potential to slow down system with frequent GC for arithmetic calculation always prefer primitive over boxed primitive and look for unintentional autoboxing in Java
There is another problem as well when you compare int variable to Integer object using == operator, the Integer object is converted to a primitive value. This can throw null pointer exception if the Integer object is null, which can crash your program.
Comparing Integer object with == in Java
Why you should not compare Integer using == in Java 5Some of the JVM cache objects of some wrapper class e.g. Integer from -128 to 127 and return same object which if compare via “ ==” can return true but after this range this validity doesn't work and to make it worse this behavior is JVM dependent so better avoid this kind of check and use equals() method. e.g.
Integer i1 = 260;
Integer i2 = 260;
if (i1 == i2) {
System.out.println("i1 and i2 is equal");
} else {
System.out.println("i1 and i2 is not equal ");
}
Here you will most probably get "i1 and i2 is not equal " at least in my machine.
because in this case, unboxing operation is not involved. The literal 260 is boxed into two different Integer objects ( again it varies between JVM to JVM) , and then those objects are compared with ==. The result is false, as the two objects are different instances, with different memory addresses. Because both sides of the == expression contain objects, no unboxing occurs.
Integer i1 = 100;
Integer i2 = 100;
if (i1 == i2) {
System.out.println("i1 and i2 is equal");
} else {
System.out.println("i1 and i2 is not equal ");
}
Here, most probably you will get the text "i1 and i2 is equal".
Because int values from -127 to 127 are in a range which most JVM will like to cache so the VM actually uses the same object instance (and therefore memory address) for both i1 and i2. As a result, == returns a true result.
This is very indeterministic and only shown by example since some JVM do optimization at certain integer value and try to return same object every time but its not guaranteed or written behavior.
So best is to avoid this kind of code in post Java 1.5 and instead use equals() method to compare Integers in Java, which is more deterministic and correct.
No comments:
Post a Comment