use*_*633 10 java generics type-inference compiler-errors jls
对于以下代码段:
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) {}
}
Run Code Online (Sandbox Code Playgroud)
第一次调用时编译器正常,但如果我取消注释第二次调用,则会抱怨.这是类型推理系统中的错误,还是有人可以解释为什么JLS中的推理规则在这里失败?
在6u43和7u45 Oracle JDK上进行了测试.
更新:似乎eclipsec接受它就好了.不幸的是我无法真正改变我们的工具链:P,但在编译器中找到差异很有意思.
错误消息,由ideone打印(很酷的工具顺便说一句):
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
Run Code Online (Sandbox Code Playgroud)
更新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) {}
}
Run Code Online (Sandbox Code Playgroud)
看起来命令行编译器同时处理有些困难
至少没有正确实例化 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) {}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
375 次 |
最近记录: |