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

爱德华·维奇

重构代码时,我偶然发现了奇怪的Java编译器(Oracle 1.8.0_101)行为。我的假设是,如果我替换所有出现List<T>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) {
}

此代码进行编译当我更换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) {
}

不再编译

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

Java泛型-编译器错误

泛型和迭代器的Java编译器错误

调用泛型方法java的编译器错误

Java:递归泛型编译器错误

泛型混淆:欺骗编译器

为什么Java编译器不重写此代码?

兼容的Java编译器可以优化此代码吗?

是否是试图编译此代码的错误导致IDE终止或编译器无法运行?

是否允许此编译器转换?

使用Java泛型并将List作为方法参数的编译器错误并引发泛型异常

Java泛型:Eclipse中未显示编译器错误

Eclipse Java 编译器推断出错误的泛型类型?

为什么Java编译器失去构造函数实例化轨道泛型类型的?

如何提取从Java泛型类类满足编译器?

在Java中转换为泛型方法类型变量时出现编译器警告

当我用Java迭代非泛型映射时,编译器会抱怨

为什么这个java接口定义使用编译器接受的泛型?

责任链设计原理中的Java泛型编译器错误

Java泛型错误:来自命令行编译器的不可转换类型

Java-本地类和泛型,为什么会出现编译器警告?

保存ArrayLists时由泛型引起的Java编译器警告

为什么运算符<对于Java泛型有编译器错误?

MSVC 是否有解决此代码的“内部编译器错误”的方法?

编译器如何推断泛型方法的类型?

声明泛型类型时的编译器警告

为什么编译器不推断泛型

解决泛型类型约束中的编译器错误

为什么这种带有泛型的Kotlin代码会产生Type Mismatch编译器错误?

泛型:有没有办法让编译器检查T是否是特定的UIView子类?