incompatible types: SomeX cannot be converted to CAP#1

10,510

Solution 1

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.

Solution 2

So, the question is actually already answered in "How can I add to List<? extends Number> data structures?", but googling just did not bring that match.

Short answer, as far as I get it, is below:

class Main {
    private static class SomeX {}

    private static class SomeY extends SomeX {}

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

Because <? extends SomeX> is rather a lower-bound limit for Collection type than item type - it will be possible to assign instance of collection with higher-bounded value and, taking this into account, putting SomeX into such collection is not type-safe from compiler's perspective.

Share:
10,510
Xtra Coder
Author by

Xtra Coder

Updated on June 09, 2022

Comments

  • Xtra Coder
    Xtra Coder almost 2 years

    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)