I'm learning about generics and am slightly confused. I'm confused about the difference between the input type and returned type for a class using generics.
Stack<Integer> even = new Stack<>();
// pushing values in stack
even.push(0);
even.push(2);
System.out.println(even.pop().getClass().getSimpleName());
System.out.println("pop => " even.pop());
We are pushing in an int value of 0 and 2. But the first print statement will print "Integer". If the stack is declared with Integer as its generic type, why are we able to push in a primitive "int"? If we can push in a primitive "int" why is the pop() class returning a wrapper class "Integer"?
I'm clearly misunderstanding something about generics.
CodePudding user response:
It happens because of someting called autoboxing.
Autoboxing is the automatic conversion that the Java compiler makes between the primitive types and their corresponding object wrapper classes. For example, converting an int to an Integer, a double to a Double, and so on. If the conversion goes the other way, this is called unboxing.
The simplest example:
Character ch = 'a';
That is what happens here:
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i = 2)
li.add(i);
The compiler creates an Integer object from i and adds the object to the list.
List<Integer> li = new ArrayList<>();
for (int i = 1; i < 50; i = 2)
li.add(Integer.valueOf(i));
The same thing for you stack.
CodePudding user response:
You cannot have a generics declared as primitive types, because they are not classes. They are other thing (primitive types, of course). Instead, you use the corresponding wrapper class.
When you do the push(int)
, there is an implicit cast to the wrapper class Integer
via the Integer#valueOf(int)
method.
stack.push(0);
Is transformed, by the compiler and without asking into this
stack.push(Integer.valueOf(0))
For the same reason, you can do something like this
Integer n = 3;
And get no errors.