2

Trying to get some generics to work, I ended up with the following simplified example:

    Set<? extends Number> setOfNumbers;
    Set<? extends Integer> setOfIntegers = new HashSet<>();
    setOfNumbers = setOfIntegers; // compiles

    List<Set<? extends Number>> listOfSetOfNumbers;
    List<Set<? extends Integer>> listOfSetOfIntegers = new LinkedList<>();
    listOfSetOfNumbers = listOfSetOfIntegers; // does not compile

I understand (clearly not completely) and use type bounds often, but this case confuses me. If anything, I would expect listOfSetOfIntegers = listOfSetOfNumber; not to work (and indeed it does not either).

Why is that?

user118967
  • 4,895
  • 5
  • 33
  • 54
  • 1
    Consider: `listOfSetOfNumbers.add(Collections.singleton(1f)); Integer i = listOfSetOfIntegers.get(0).iterator().next();` – shmosel Nov 30 '18 at 02:13
  • 1
    The key insight here is that `Set extends Number>` does **not** mean "a set of things which are all subtypes of `Number`". It sounds like it should mean that, but it doesn't. (If you want that, it's `Set`.) No, what `Set extends Number>` really means is "a set of things which are all of some specific type -- I can't tell you what type it is, but I promise that whatever type it is, it is at least implicitly convertible to `Number`". Because the type is actually not known, the compiler has to assume the worst. Perhaps it's really a `Set` or `Set` or something. – Daniel Pryden Nov 30 '18 at 02:25

0 Answers0