2

I have a List<? extends MyClass> list and I want to add into this list objects whose class extends MyClass and objects which are instances of MyClass:

list.add(new ClassThatExtendsMyClass());
list.add(new MyClass());

but eclipse shows the build error:

The method add(capture#9-of ? extends MyClass) in the type List is not applicable for the arguments (MyClass)

How can I get around this?

bcsb1001
  • 2,834
  • 3
  • 24
  • 35
Eduardo
  • 6,900
  • 17
  • 77
  • 121
  • have a look here, it's to do with the implementation of generics. http://stackoverflow.com/a/3716945/4112645 – PeterK Oct 10 '14 at 16:17

5 Answers5

4

Java keyword extends in generic type of reference is used to restrict actual generic type realization to be no less derived than the named type. Especially it can be a subclass. One should use it in case type is used to extract values and operate on them. You then use the interface of the base class not concerning the actual type (realization/implementation) of that class.

When you've got a specific class and need to pass (put) into collection, or other generic class object, the reference to point at that object should have super keyword, which restricts the actual object to be no more derived than the named type.

Code example below. Assume we have classes Base and Derived, where Derived extends Base, class Base have an interface method foo() and both have default constructor.

void service() {
    List<Base> theList = new ArrayList<Base>();

    produceObjects(theList);
    consumeObjects(theList);
}

void produceObjects(List<? super Base> consumerList) {
    consumerList.add(new Derived());
}

void consumeObjects(List<? extends Base> producerList) {
    for (Base base : producerList) {
        base.foo();
    }
}
Krzysztof Jabłoński
  • 1,890
  • 1
  • 20
  • 29
2

You can declare your reference as List<MyClass>.

You'll be able to add anything extending MyClass, including instances of MyClass.

Mena
  • 47,782
  • 11
  • 87
  • 106
2

This is not possible. List<? extends MyClass> list could actually point to a ArrayList<ClassThatExtendsMyClass>. Which can't hold instances of some other subclass of MyClass.

List<? extends Number> numbers = new ArrayList<Integer>();
numbers.add(Long.valueOf(2)); // not possible since 'Integer' array can't hold Longs

If you want to add things you should declare your variable 'list' as List<? super MyClass>. This will enable you to add any subclass of 'MyClass' into the list.

List<? super Number> numbers = new ArrayList<Number>();
numbers.add(Long.valueOf(2)); 

This is known as the 'get' and 'put' principle. If you want to 'get' stuff you need to have the List<? extends MyClass> syntax whilst if you want to 'put' stuff you need to have the List<? super MyClass> syntax. Ofcourse if you need to do both then you need to use List<MyClass> syntax.

Dev Blanked
  • 8,555
  • 3
  • 26
  • 32
0

Try this:

List<MyClass>

It should work

WidWing
  • 176
  • 1
  • 10
-1

Define it this way:

List<MyClass> list
sethmuss
  • 169
  • 9