Reputation: 35
If there is a generic type node<E>
with two operations like setData(E Type)
and E getData()
and let s0
be a instance of node
by node<? extends Number>
then why don't the compiler allow me to use s0.setData(Number Type)
at least? I can understand why other types are not allowed but why not allow the setData
to put in a Number type as we are sure that the type of node will be at least number?
My code looks like this:
class Node<E> {
private E data;
// ...
public void setData(E obj) { data = obj; } // (1)
public E getData() { return data; } // (2)
// ...
}
Node<? extends Number> s0 = new Node<Number>();
s0.setData(200); //this is not allowed why?
Node<Number> s0 = new Node<Number>();
s0.setData(100); //But this is allowed!
Upvotes: 2
Views: 95
Reputation: 425033
You have declared the type a Node<? extends Number>
. What you assign to it is irrelevant.
As far as the compiler is concerned it could be any of the following:
Node<Integer>
Node<Float>
Node<Double>
And it has no way of knowing which type is the actual type.
You are trying to pass an (auto-boxed) Integer
, but the compiler can't know that the actual type can accept an Integer
.
Upvotes: 1
Reputation: 124225
Lets say you have reference Node<? extends Fruits> s0
. It means that it can point to
Node<? extends Fruit> s0 = new Node<Fruit>;
but also
Node<? extends Fruit> s0 = new Node<Apple>;
and
Node<? extends Fruit> s0 = new Node<Banana>;
How do you think, would it be safe to let it add Fruit
to Bananas or Apples? Or Banana to Apples? What if Apple and Banana contains methods that Fruit doesn't.
Upvotes: 0
Reputation: 328608
In subtance: because a Node<Integer>
for example, is not a Node<Double>
. It is not even a Node<Number>
.
Example:
Node<? extends Number> s0 = new Node<Integer> ();
s0.setData(Double.valueOf(2.0d)); //that's not possible...
Actually, because we don't know what the generic type of s0
is, you won't be able to call the setData
method on anything but null
...
Upvotes: 0