此代码是否利用 Java 编译器泛型验证限制

Does this code exploit Java compiler generics verification limitations

在重构代码时,我偶然发现了奇怪的 Java 编译器 (Oracle 1.8.0_101) 行为。我的假设是,如果我用 T 替换所有出现的 List<T>(不使用 List 中的任何方法)代码应该编译,如果它在更改之前编译的话。

现在看看这段代码:

interface Mapper<T, U extends MapperProvider<U>> extends Function<T, List<U>> {}

interface MapperProvider<V> {
    Mapper<V, ?> provide();
}

private <V extends MapperProvider<V>> void use(V c) {
    use2(c.provide().apply(c));
}

private <W extends MapperProvider<W>> void use2(List<W> c) {
}

此代码compiles。当我将 List<U> 替换为 U 并将 List<W> 替换为 W 时:

interface Mapper<T, U extends MapperProvider<U>> extends Function<T, U> {}

interface MapperProvider<V> {
    Mapper<V, ?> provide();
}

private <V extends MapperProvider<V>> void use(V c) {
    use2(c.provide().apply(c));
}

private <W extends MapperProvider<W>> void use2(W c) {
}

does not compile 再:

Error:(201, 17) java: method use2 in class Test cannot be applied to given types;
  required: W
  found: capture#1 of ?
  reason: inference variable W has incompatible bounds
    equality constraints: capture#1 of ?
    lower bounds: MapperProvider<capture#1 of ?>

我认为这是正确的。 use2 应声明为接收 MapperProvider<?>

为什么 Java 编译器将第一个版本视为合法?

看来 Oracle 认为这是一个错误。我打开了一个错误报告,Oracle 确认:JDK-8172222