Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

incompatible types: SomeX cannot be converted to CAP#1 [duplicate]

Tags:

java

generics

I can't grasp what is wrong here

import java.util.*;

class Main {
    private static class SomeX {}

    void doSomethingWithX(SomeX someX) {
        Collection<? extends SomeX> colectionOfX = new ArrayList<>();
        colectionOfX.add(someX);
    }
}

javac says following:

  Main.java:8: error: method add in interface Collection<E> cannot be applied to given types;
          colectionOfX.add(someX);
                      ^
    required: CAP#1
    found: SomeX
    reason: argument mismatch; SomeX cannot be converted to CAP#1
    where E is a type-variable:
      E extends Object declared in interface Collection
    where CAP#1 is a fresh type-variable:
      CAP#1 extends SomeX from capture of ? extends SomeX

To my understanding extends limits the lower bound of CAP#1 to SomeX and SomeX itself should satisfy the limit.

What's wrong? (Compiled with javac 1.8.0_102)

like image 529
Xtra Coder Avatar asked Oct 29 '22 19:10

Xtra Coder


1 Answers

If you want to allow colectionOfX to contain any instance of SomeX, it should be declared as :

Collection<SomeX> colectionOfX = new ArrayList<>();

When you declare it as

Collection<? extends SomeX> colectionOfX = ...;

it means you can assign to it any Collection that holds elements of some type that is either SomeX or a sub-class of SomeX.

For example, you can assign to it a List<SomeBX>, where SomeBX extends SomeX. In that case only instances of SomeBX can be added to the collection. So if you try to add to the collection a SomeX instance which is not a SomeBX (for example, an instance of SomeAX, which is also a sub-class of SomeX), it would be invalid.

like image 157
Eran Avatar answered Nov 14 '22 21:11

Eran