泛型是不变的,但是编译没有错误

时间:2017-07-27 17:13:47

标签: java generics invariance

我遇到了类型不匹配错误,直到我为此重构了代码:

    public final Stream<Map.Entry<E, Integer>> orderedStreamOfEntries() {
        return this.m_map.entrySet()
                .stream()
                .sorted(Comparator.comparingInt(Entry::getValue))
                .map(AbstractMap.SimpleImmutableEntry::new);            
    }
  • 返回类型为Stream<Entry<E, Integer>>
  • 此例程结束时的流类型为Stream<SimpleImmutableEntry<E, Integer>>

形式类型参数E具有以下定义:

<E extends Enum<E> & MyCustomInterface>

我不明白为什么这似乎是编译器可以接受的。因为Java泛型是不变的,即使java.util.AbstractMap.SimpleImmutableEntry实现java.util.Map.Entry,我也会说Stream<SimpleImmutableEntry<>>不是返回类型的子类型Stream<Entry<>>

1 个答案:

答案 0 :(得分:2)

你犯了两个错误。第一个假设SimpleImmutableEntry::newFunction<Entry, SimpleImmutableEntry> *,实际上它可以解释为Function<Entry, Entry> 恰好返回 a SimpleImmutableEntry

其次,查看map()的签名:

<R> Stream<R> map(Function<? super T, ? extends R> mapper)

通过返回? extends R,该方法可以自由地将R解释为lambdas返回类型的超类,这意味着即使Function<Entry, SimpleImmutableEntry>也可能导致Stream<Entry>,甚至是Stream<Object>

实际解释取决于推断的返回类型,在您的情况下为Stream<Entry>

*用于简洁的原始条目类型。