A Wrapper Class is used to convert primitive into object and object into primitive. Similarly by using Autoboxing and Unboxing we can do the same then what is the difference in these two:
1-Concept wise
2-Code wise???
Auto-boxing and auto-unboxing is just the compiler silently helping you create and use primitive wrapper objects.
For example, the int primitive type has wrapper class called Integer. You wrap and unwrap as follows:
int myInt = 7;
// Wrap the primitive value
Integer myWrappedInt = Integer.valueOf(myInt);
// Unwrap the value
int myOtherInt = myWrappedInt.intValue();
With auto-boxing and auto-unboxing, you don't have to do all that boiler-plate stuff:
int myInt = 7;
// Wrap the primitive value
Integer myWrappedInt = myInt; // Compiler auto-boxes
// Unwrap the value
int myOtherInt = myWrappedInt; // Compiler auto-unboxes
It's just a syntactic sugar, handled by the compiler. The generated byte code is the same.
Wrapper classes in java provides a mechanism to convert primitive into object and object into primitive. Whereas automatic boxing and unboxing allows you to do that conversion automatically. Autoboxing and auto unboxing are legal in java since Java 5.
public class Main {
public static void main(String[] args) {
int x=100;
Integer iob;
iob=x;//illegal upto JDK1.4
iob= Integer.valueOf(x); //legal=> Boxing,Wrapping
iob=x; //Legal since JDK1.5=> Auto Boxing
}
}
Here x is a primitive variable, iob is a reference variable. So only an address can be assigned into this iob reference. iob=Integer.valueOf(x) will convert primitive integer into integer object. This conversion can be implied as wrapping. iob=x will do the same thing. It also saves a lot of coding.
public class Main {
public static void main(String[] args) {
Integer iob= new Integer(100);
int x;
x=iob;//illegal upto JDK1.4
x=iob.intValue(); //unboxing,unwrapping
x=iob; //legal since JDK1.5=> auto unboxing
}
}
Here iob.intValue() will take the value of integer object and it will assign that value into x. x=iob does the same thing except you don't need to write conversion code.
Related
I am directly casting my int primitive type variable to Integer object like below:
int intValue = 0;
Integer value = (Integer) intValue;
Is this fine or will cause some unexpected problems?
Autoboxing is the automatic conversion that the Java compiler makes
between the primitive types and their corresponding object wrapper
classes.
int intValue = 0;
Integer value = intValue; // by Autoboxing
you can also convert it using valueOf method of wrapper class
Integer value = Integer.valueOf(intValue)
Check What code does the compiler generate for autoboxing? if you still have doubts.
public static void main(String []args){
Integer a = new Integer(9);
d(a);
System.out.print(a) ;
}
public static void d(int z){
z=z+2;
}
or suppose I write
public static void main(String []args){
int a = 9;
d(a);
System.out.print(a) ;
}
public static void d(int z){
z=z+2;
}
but the output is the same for both: 9. Can anyone explain me in detail why?
Because JAVA is PASS BY VALUE not PASS BY REFERENCE.
Let us understand it this way,
Your main function has a local variable z whose scope is limited to main only
and your d function has another local variable z whose scope is limited to d only
So, in your d fucntion, you are basically creating a new integer literal 11 and putting it to local variable z whose scope is limited to d function only and not the variable z of main.
In your code with Integer a process called unboxing occurs. The Integer-instance is unboxed to a primitive int when calling your method d. See this to better understand how autoboxing and unboxing works.
As for your z=z+2 inside the method d. Java objects are passed-by-reference, but Java primitives or Immutable objects (like Strings) are passed-by-value. Since your method d has a primitive parameter int it's passed-by-value in this case. Your z=z+2 isn't returned however.
If you would add System.out.println(z); right after z=z+2 it will indeed print 11. So why isn't the a in your main-method changed to 11 and how can you accomplish this? As I mentioned, it's passed-by-value for primitives. You'll need to return the new value and set the a in the main method with it. If you change your code to this it will work:
public static void main(String []args){
int a = 9;
a = d(a);
System.out.print(a);
}
public static int d(int z){
return z+2;
}
Try it online.
As you can see, the void d is changed to int d, and we return the result of z+2. We then overwrite the value of a with this new result with a = d(a); in the main-method.
Java has a concept of AutoBoxing and Auto unboxing for primitive datatypes.
Since primitves like int, float double, long etc are technically not objects, they have their corresponding Classes which can be instantiated with the primitive value to treat them as objects.
So to reduce the pain, java automatically converts int to Integer and Integer to int where ever applicable.
If you are wondering why the addition value has not reflected, though it is an Integer object on performing addition, a new int object will be resulted. so it wont reflect directly. You can return the value from the method you call and assign to it.
Java passes variables by value, not by reference. If you think that passing an object and changing the value of its data member would work, it won't. In that case, too, a copy of that object will be passed, not the original object. The only solution is to declare the variable as static that can be changed from anywhere.
it's all because of Autoboxing and Unboxing feature of java which provide the functionality of converting primitive to object(Wrapper) type and vice-versa. for better understanding you can check here
. I hope it will clear all your doubts.
What is the difference between the following:
Integer in = (Integer)y;
and
Integer in = new Integer(y);
I want to convert int type to Integer type and vice versa. Here is my code for doing that:
public class CompareToDemo {
public static void main(String[] args) {
// Integer x=5;
int y=25;
System.out.println(y+" this is int variable");
Integer in = (Integer)y;
//Integer in = new Integer(y);
if(in instanceof Integer){
System.out.println(in +" this is Integer variable");
}
}
}
If all you want to do is to convert an int primitive to an Integer object,
you have four options
Integer in = (Integer)y; // 1 explicit cast
Integer in = y; // 2 implicit cast (autoboxing)
Integer in = new Integer(y); // 3 explicit constructor
Integer in = Integer.valueOf(y); // 4 static factory method
The most preferable way here is 2 (autoboxing). The explicit constructor (3) is the less preferable, as it might have some small performance hit.
Also, they are not strictly equivalent. Consider:
public static void main(String[] args) {
int x = 25;
Integer a = new Integer(x);
Integer b = new Integer(x);
System.out.println(a == b); // false
Integer c = Integer.valueOf(x);
Integer d = Integer.valueOf(x);
System.out.println(c == d); // true
Integer e = (Integer)x;
Integer f = (Integer)x;
System.out.println(e == f); // true
}
This is because small integers are cached (details here).
Briefly speaking,
The line Integer in = (Integer)y; uses an unnecessary cast.
The line Integer in = new Integer(y); creates an Integer instance.
Each case in detail
First, let's consider the case with explicit casting.
Integer i = (Integer)10;
The compiler understands that 10 is an int primitive type and the fact that it has to be wrapped by its Integer to make it compiles. It seems javac will make the following:
Integer i = (Integer)Integer.valueOf(10);
But the compiler is smart enough to do unnecessary casting, (Integer) just will be omitted:
Integer i = Integer.valueOf(10);
Next, there is the case with instance creation.
Integer i = new Integer(10);
Here is all simply. A new instance of Integer class will be created anyway. But, as the documentation says, usually, it is not appropriate way:
It is rarely appropriate to use these constructors. The static factories valueOf() are generally a better choice, as it is likely to yield significantly better space and time performance.
Conclusion
In everyday code writing, we usually use autoboxing and unboxing. They are automatic conversions between the primitive types and their corresponding object wrapper classes (has been introduced in Java 5). So you needn't think much about Xxx.valueOf(xxx) and .xxxValue() methods. It is so convenient, isn't it?
Integer i = 10; // autoboxing
int j = i; // unboxing
For every primitive type in java, there is a corresponding wrapper class. You can convert between these primitive type and corresponding wrapper class. This is called boxing and unboxing. When you write
Integer in = (Integer)y; //this is unnecessary casting
or
Integer in = new Integer(y); //create a new instance of Integer class
You're mainly converting between primitive type and wrapper class. But Java has a feature called Auto Boxing and Unboxing Where java will do these casting for you. Just write
int iPrimi = 20;
Integer iWrapper = iPrimi; //Autoboxing
int iPrimi2 = iWrapper; //Auto unboxing
Autoboxing and Unboxing decrease performance. Primitives seems to be 2-3 times faster then it’s Integer equivalent. So do not use them if you don't need to.
I cant figure out how the int 7 is consider as object in below example.
The sifer(7) is consider to be method sifer(Object o). I am not able to get it how this happened. In one of my java reference book it says Int can be boxed to an Integer and then "widened" to an object. I am not sure what that means.
>> Class A
class A { }
>> Class B
class B extends A { }
>> Class ComingThru
public class ComingThru {
static String s ="-";
static void sifer(A[] ...a2)
{
s = s + "1";
}
static void sifer(B[] b1)
{
s += "3";
}
static void sifer(Object o)
{
s += "4";
}
public static void main(String[] args) {
// TODO Auto-generated method stub
A[] aa= new A[2];
B[] ba = new B[2];
//sifer(aa);
//sifer(ba);
sifer(7);
System.out.println(s);
}
}
Since there is no sifer(int) method, the compiler will try to find the "closest match". In this case, the other 2 sifer methods take arrays as parameters, which an int clearly isn't.
The last method, sifer(Object) can be applied to any objects, including an Integer so that's the method that is used for sifer(7).
The reality is a little more complex, and the JVM will look for a matching mathod in the following order:
an identity conversion
in your case: sifer(int) but there is no such method
a widening primitive conversion
in your case: sifer(long) for example, but there is no such method
a widening reference conversion
in your case: not applicable, int is not an object
a boxing conversion optionally followed by widening reference conversion
in your case that's what's happening: int is boxed to Integer which is widened to Object
an unboxing conversion optionally followed by a widening primitive conversion
in your case: not applicable
1. Above code provides an classic example of Method Overloading, along with AutoBoxing and Auto-UnBoxing which came by Java 1.5, cause manual Boxing and Unboxing was a pain.
2. The sifer(A[]... a2) and sifer(B[] b1) both accepts Array type Arguments in its parameter, which no way matches int. So now we are left only with sifer(Object o).
3. Now the int will be converted into Wrapper Object Integer Automatically.
You can verify it by doing this in snifer(Object o) method.
o.getClass().getName();
See this link for further details:
http://docs.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html
7 will be auto boxed to Integer which is an Object
Also See
java: boolean instanceOf Boolean?
Steps as below-
The int (7) was boxed to a Integer.
The Integer reference was widened to an Object (since Integer extends Object).
The sifer() method got an Object reference that actually refers to a Integer
object.
What is happening when a java.lang.Double object is initialized without using a call to the constructor but instead using a primitive? It appears to work but I'm not quite sure why. Is there some kind of implicit conversion going on with the compiler? This is using Java 5.
public class Foo {
public static void main(String[] args) {
Double d = 5.1;
System.out.println(d.toString());
}
}
This is called Autoboxing which is a feature that was added in Java 5. It will automatically convert between primitive types and the wrapper types such as double (the primitive) and java.lang.Double (the object wrapper). The java compiler automatically transforms the line:
Double d = 5.1;
into:
Double d = Double.valueOf(5.1);
It is called AutoBoxing
Autoboxing and Auto-Unboxing of
Primitive Types Converting between
primitive types, like int, boolean,
and their equivalent Object-based
counterparts like Integer and Boolean,
can require unnecessary amounts of
extra coding, especially if the
conversion is only needed for a method
call to the Collections API, for
example.
The autoboxing and auto-unboxing of
Java primitives produces code that is
more concise and easier to follow. In
the next example an int is being
stored and then retrieved from an
ArrayList. The 5.0 version leaves the
conversion required to transition to
an Integer and back to the compiler.
Before
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, new Integer(42));
int total = (list.get(0)).intValue();
After
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(0, 42);
int total = list.get(0);
It's called autoboxing.