gpt4 book ai didi

Java 有界泛型 : Type inference bug?(方法调用,JLS 15.12.2.7)

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:02:02 25 4
gpt4 key购买 nike

对于下面的代码片段:

import java.util.List;

public class Main {
interface Interface1<T> {}
interface Interface2<T> extends Interface1<T> {}
static class Bound {}
interface BoundedI1<T extends Bound> extends Interface1<T> {}
interface BoundedI2<T extends Bound> extends Interface2<T> {}

public static void main(String[] args) {
test((List<BoundedI2<?>>) null);
//test2((List<BoundedI2<?>>) null);
}

public static void test(List<? extends Interface2<? extends Bound>> list) { test2(list); }

public static void test2(List<? extends Interface1<? extends Bound>> list) {}
}

编译器对第一个调用没问题,但如果我取消对第二个调用的注释,编译器就会报错。这是类型推理系统中的错误,还是有人可以解释为什么 JLS 中的推理规则在这里失败?

在 6u43 和 7u45 Oracle JDK 上测试。

更新:似乎 eclipsec 接受得很好。不幸的是,我无法真正改变我们的工具链 :P,但发现编译器中的差异很有趣。

错误消息,由 ideone(酷工具 btw)打印:

Main.java:12: error: method test2 in class Main cannot be applied to given types;
test2((List<BoundedI2<?>>) null);
^
required: List<? extends Interface1<? extends Bound>>
found: List<BoundedI2<?>>
reason: actual argument List<BoundedI2<?>> cannot be converted to List<? extends Interface1<? extends Bound>> by method invocation conversion

更新 2:编译正常,这表明编译器确实认为 BoundedI2<?>可分配给 Interface1<? extends Bound> ,这似乎更直接地与 JLS 相矛盾:

public class Main {
interface Interface1<T> {}
interface Interface2<T> extends Interface1<T> {}
static class Bound {}
interface BoundedI1<T extends Bound> extends Interface1<T> {}
interface BoundedI2<T extends Bound> extends Interface2<T> {}

public static void main(String[] args) {
test((List<BoundedI2<?>>) null);
//test2((List<BoundedI2<?>>) null);
test3((BoundedI2<?>) null);
}

public static void test(List<? extends Interface2<? extends Bound>> list) { test2(list); }

public static void test2(List<? extends Interface1<? extends Bound>> list) {}
public static void test3(Interface1<? extends Bound> instance) {}
}

最佳答案

看起来命令行编译器同时处理有一些困难

  • BoundedI2 在必须是“绑定(bind)”的 T 上是通用的这一事实
  • Interface2 正在扩展 Interface1 的事实

至少没有正确实例化 BoundedI2。确实奇怪的是,在同一个 JDK 上配置的 Eclipse 编译得很好......请注意,Eclipse 使用它的内部编译器来处理键入时的增量重新计算,因此它根本不调用 JDK 的编译器(请参阅 org/eclipse/jdt/internal/编译包)。

此修改通过强制 BoundedI2 为具体类型而不是类型推断,使其在 Eclipse 和命令行中都能正常编译:

import java.util.List;

public class PerfTest {
interface Interface1<T> {}
interface Interface2<T> extends Interface1<T> {}
static class Bound {}
interface BoundedI1<T extends Bound> extends Interface1<T> {}
interface BoundedI2<T extends Bound> extends Interface2<T> {}
static class Actual extends Bound {}

public static void main(String[] args) {
test((List<BoundedI2<Actual>>) null);
test2((List<BoundedI2<Actual>>) null);
}

public static void test(List<? extends Interface2<? extends Bound>> list) { test2(list); }

public static void test2(List<? extends Interface1<? extends Bound>> list) {}
}

关于Java 有界泛型 : Type inference bug?(方法调用,JLS 15.12.2.7),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24817306/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com