3

The code below makes complete sense to me - its about adding an element of some type which is supertype of type T and type S is definitely such a super type , so why the compiler refuses to add 'element' into the collection ?

class GenericType<S,T extends S>{
   void add1(Collection<? super T> col ,S element ){
        col.add(element);  // error
       // The method add(capture#9-of ? super T) in the type 
       // Collection<capture#9-of ? super T> is not applicable for the arguments (S)
    }
}
Bhaskar
  • 7,443
  • 5
  • 39
  • 51

4 Answers4

5

Thake an example, if A <- B <- C where <- means that is the supertype, then if S = B and T = C you cannot add an instance of S to a collection of T.

A supertype of T may be the supertype or a subtype of another supertype of T (in this case S).

Kru
  • 4,195
  • 24
  • 31
  • yes I agree with your derivation , but the fact still remains that S is a supertype - so why is that fact not deemed sufficient for allowing this addition ? I can see that allowing so will also lead to a possible runtime exception , so is it because the designers decided to avoid getting into such runtime situations ? if you , then whats the difference between Collection super T> and Collection in above usage ? – Bhaskar Jun 07 '11 at 12:11
  • correct answer indeed , but have to give it to Michael for letting me understand it in prose. – Bhaskar Jun 07 '11 at 12:32
2

Collection<? super T> does not mean "a collection that can contain T and any superclass of it" - it's actually not possible to formulate that restriction. What it means is "a collection that can only contain instances of some specific class which is a superclass of T" - basically it ensures that you can add a T to the collection.

The method can be called with a Collection<T>, yet you want to add an S to it.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • Given what you say , how is then this declaration different from something that does *not* use wildcard ( Collection instead of Collection super T> ) ? – Bhaskar Jun 07 '11 at 12:07
  • @Bhaskar: the wildcard also allows you to call the method with a Collection or a Collection - everything you can add a T to. – Michael Borgwardt Jun 07 '11 at 12:20
2
new GenericType<Object,Integer>().add1(new ArrayList<Integer>(), "");
Tom Hawtin - tackline
  • 145,806
  • 30
  • 211
  • 305
  • +1 for a valid concrete and unsafe example. Though it might be more clear that you're exercising the "super" keyword if you passed in an `ArrayList`. Using `ArrayList` does show the most obvious flaw in the OP's reasoning, in that `List super T>` admits a `List` which obviously won't accept an arbitrary supertype of `T`. – Mark Peters Jun 07 '11 at 12:23
0

You are trying to put an element of type S into a collection of type T. Generics aren't polymorphic. You have to take notice of 2 problems here. you are trying to create an Collection of type concreteObject extends Object and are adding an object So when you have

Car extends Vehicle{}
ElectricCar extends Car{}

you are trying to do

Collection<? extends Car> collection;
collection.add(new Vehicle());

The second problem lies with the non-polymorphism nature of Generics. See this great explanation -> Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?

Community
  • 1
  • 1
jelle
  • 770
  • 7
  • 26