2

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!
Vishakh PC
  • 35
  • 5

3 Answers3

1

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>
  • etc

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.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • Why not, have't we told it that it could atleast be a Number or any of its subtype via ? extends Number and is't integer a subtype for Number? – Vishakh PC Mar 13 '13 at 04:06
  • Why not? Because you could have assigned a `Node` to the variable `Node extends Number> s0`. What do you think will happen if you call the `setData()` method of a `Node` with an `Integer`? – Bohemian Mar 13 '13 at 04:32
  • With reference to the code I have posted, Why can't I add any subtype? at the same type you can do setData(200) when the type is just Node – Vishakh PC Mar 13 '13 at 04:37
  • No!!! The type is NOT `Node`! The type is `Node extends Number>`. You have *assigned* a `Node`, but the compiler only looks at the *declared* type. It's all explained in my answer - please re-read it carefully. – Bohemian Mar 13 '13 at 07:09
0

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.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • We know that node can atleast be fruit then why not allow add a subtype of fruit. Why is the add operation not allowed with extend and only with super? I could always do s0.setFruit(Apple) and get it back using getFruit() where am I violating type safety? – Vishakh PC Mar 13 '13 at 03:50
  • If Java would allow to add any Fruits via `Node extends Fruit> s0`, then it would mean that it would be possible to also add Bananas to Apples. Take a look `Node extends Fruit> s1 = new Node; s1.add(new Banana());` would be correct, because `Banana extends Fruit`. – Pshemo Mar 13 '13 at 04:00
0

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...

Community
  • 1
  • 1
assylias
  • 321,522
  • 82
  • 660
  • 783
  • But have we not sure that it could atleast be a number, then why not allow to put a number in? – Vishakh PC Mar 13 '13 at 03:45
  • @VishakhPC In my example, s0 is really about Integer, so there is no reason why the compiler would allow you to add Doubles or BigDecimals in there. – assylias Mar 13 '13 at 03:46