Java有界泛型:类型推断错误? (方法调用,JLS 15.12.2.7)
有关以下代码片段:
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) {} } 编译器第一次调用就OK了,但是如果我取消了第二次调用,则会抱怨.这是类型推理系统中的错误,还是有人可以解释为什么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扩展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在T上是通用的事实,它必须是“绑定” 至少没有正确地确定BoundedI2.奇怪的是,在同一个JDK上配置的Eclipse编译它很好…注意,Eclipse使用它的内部编译器,以便在键入时处理增量重新编译,因此它根本不会调用JDK的编译器(请参阅org / eclipse / jdt / internal / compiler包). 这个修改使得它可以在Eclipse和命令行中编译,通过强制BoundedI2是一个具体的类型,而不是类型推断: 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) {} } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |