对于以下代码段:
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。确实奇怪的是,在同一个JDK上配置的Eclipse可以很好地进行编译...请注意,Eclipse使用它的内部编译器来处理您键入时的增量重新计算,因此它根本不会调用JDK的编译器(请参阅org / eclipse / jdt / internal / compiler包)。
通过强制将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) {}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句