4

Possible Duplicate:
java generics super keyword

I am not able to relate my knowledge with the below sample program. Please see the below sample program then my doubts are below that program.

import java.util.*;
class A { }
class B extends A { }
class C extends B { }

public class sampleprog {

    public static void main(String[] args) {

        List<? super A> list1 = new ArrayList<A>();
        list1.add(new A());//valid. ok
        list1.add(new B());//valid, why? it is not super to A?
        list1.add(new C());//valid, why? it is not super to A?

        List<? super B> list2 = new ArrayList<A>();
        list2.add(new A());//not valid. why? it is also super to B!!!
        list2.add(new B());
        list2.add(new C());

        List<? super C> list3 = new ArrayList<C>();
        list3.add(new A());//not valid, why? It is super to A so should be valid!!!
        list3.add(new B());//not valid, why? It is super to A so should be valid!!!
        list3.add(new C());
    }
}

My Doubts: - As far as I know ? super T means any class you can add that is super to T but here output is different? Even subclass also added successfully that is totally confusing. - output is not different with list initialization (List<? super C> list3 = new ArrayList<C>();) . In this initialization, I assigned list of A or B, output was same!

Please clear my doubts.

Community
  • 1
  • 1
sHAILU
  • 165
  • 1
  • 10

4 Answers4

1

If we use ? super in a generic declaration, the reference can point to same generic type of collection or super generic type of collection. So everything that passes a IS-A test is valid in this case.

Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
jagamot
  • 5,348
  • 18
  • 59
  • 96
  • but "? super B" clearly mentioned that any class that is super to B. So A and other classes should be valid but not C? But as per the output, C is valid!!! – sHAILU Jan 02 '13 at 04:33
1

List<? super B> means that

List<? super B> list1 = new ArrayList<A>();
List<? super B> list1 = new ArrayList<B>();

are allowed. ArrayList<A> is super of ArrayList<B>, isn't it? Can we add B's and C's to both ArrayList<A> and ArrayList<B>? Yes we can. Can we add A's? Only to ArrayList<A>. But List<? super B> is allowed to point to ArrayList<B> too. So we cannot add A's to List<? super B>.

Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
1

"? super T" means any class you can add that must be an instance of T or its sub class.

So List<? super C> list3 = new ArrayList<C>(); in the list3 either you can add instance of class C or its sub class instances (SomeClass extends C).

A parent object list can have its own, child and child of child but a List that has created for a child class can not have its parent object. Hope you are clear now.

vels4j
  • 11,208
  • 5
  • 38
  • 63
  • Ya its clear now with the new definition of "? super T" but it is the definition given in scjp kathy sierra "When you use the super ...> syntax, you are telling the compiler that you can accept the type on the right-hand side of super or any of its supertypes, since—and this is the key part that makes it work—" on Page Number 619!!! Why she is saying supertypes and you are telling for subtypes? – sHAILU Jan 02 '13 at 06:10
  • let me clear you little later. – vels4j Jan 02 '13 at 07:25
  • here its explained http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#FAQ204 – vels4j Jan 02 '13 at 18:47
0

Vote up @us2012's comment.

  • For List<? super A>

    the type is A. A, B and C all subtype of A, so they can be added.

  • For List<? super B>

    the type can be A, B. Both B and C are subtype of A or B. Think about the difference between List<? super B> list2 = new ArrayList<A/B>()

  • For List<? super C>

    the type can be A, B, C. So only C is subtype of A, B or C.

For example, Machine -> Car -> SportsCar. for List<? super Machine>, no matter Machine, Car and SportsCar, they are all Machine, so it's safe to be added.

卢声远 Shengyuan Lu
  • 31,208
  • 22
  • 85
  • 130