0

Consider

List<? super Integer> lst= new ArrayList<Number>();
lst.add(new Integer(3)); //ok- why?? I expected compile error "expected add(int, Object), found add(int,CAP#1)"
lst.get(0); //ok

and

List <? extends Number> nums= new ArrayList<Integer>();
lst.add(new Integer(3));//Compile error- expected add(int, Object), found add(int,CAP#1)

On the compile state we dont know about type of <? extends Number> and have compile error. Does we know about type of <? super Integer> on compile state? Why?

St.Antario
  • 26,175
  • 41
  • 130
  • 318

1 Answers1

2

Of course - you know that whatever the value of the wildcard is, it is a superclass of Integer (by definition, from the bounds). So no matter what its concrete class is, you have a list of something that can hold an Integer. A List<Object> or List<Number> works just as well as a List<Integer> in this context.

With extends however, it's a different story. A List<? extends Number> could be a List<Double>, so it's clear that an Integer cannot be inserted into this list without violating type-safety. (In fact, nothing at all can be inserted - apart from null - for this reason.)

Andrzej Doyle
  • 102,507
  • 33
  • 189
  • 228
  • OK, thanks. Now i dont understand what differents `List super Integer> lst = new ArrayList();` from `List lst = new ArrayList();`? – St.Antario Sep 23 '13 at 16:33
  • @St.Antario Both of those lines involve two things. *First*, you define a variable called `lst`, and say what type it is. *Then*, you construct an object and assign it to this variable. The actual type of the object, and the declared type of the variable, can be different. Compare `Object a = "hello";` vs `String b = "hello";`, if that helps. The actual string is the same in both cases, but you can't call `a.length()` because the only guarantee you have of what's in `a` is that it's an `Object`. – Andrzej Doyle Sep 23 '13 at 19:42