为什么这个通用代码会编译?

时间:2011-02-22 20:04:55

标签: java generics

<X> X foo(List<? super X> list)
{
    return null;
}
void test()
{
    List<Number> list = ...;
    String s1 = this.foo(list); // huh?
}

最后一行没有任何意义,javac怎么允许呢?

现在,foo()方法也没有意义;它必须返回null,没有其他值可以以类型安全的方式返回。因此,运行时的最后一行不会引起任何问题:它为String变量赋值null。

静态地说,为什么最后一行编译? ( javac 1.6 u21 b06

3 个答案:

答案 0 :(得分:4)

  

你们使用哪些编译器?

他们可能正在使用eclipse,因为它不能在那里编译。但它从命令行编译。 Eclipse有一些不同的编译机制,以便更快地发现运行时问题。有时他们只是警告,在这种情况下,这是一个错误。

List<? super X>表示它可以是List<X>List<Object>。因此它可以编译。另一方面,它不会运行,但 javac 并不关心,它会为你编译代码。

答案 1 :(得分:0)

您的代码无法编译。方法的返回类型为<X>。当您调用方法foo时,您将作为模板参数Number传递。虽然您可以为String指定null,但方法的签名变为Number foo(),这意味着您将返回Number。因此,编译器不允许您将Number分配给String

答案 2 :(得分:0)

代码不会使用下一个JDK版本1.6.0_22-b04进行编译。错误是:

  

类型不匹配:无法从Number转换为String

我猜你对编译器错误的建议可能是真的。