奇怪的泛型问题

时间:2010-06-28 13:38:50

标签: java generics compiler-construction

有谁知道为什么以下代码无法编译,在编译期间我得到不兼容的类型异常?

public class Test<T> {

public static void main(String[] args)
{
    // using Test<?> solves the compilation error
    Test test = new Test();

    // getting error incompatible types:
    // found   : java.lang.Object
    // required: java.lang.Integer
    Integer number = test.getDays().get(0);
}


private List<Integer> getDays() {
    return new ArrayList<Integer>();
}

}

为什么使用带有无界通配符的Test解决了这个问题? 我正在使用java版本1.6.0_12

6 个答案:

答案 0 :(得分:8)

我将问题解释为当返回类型不依赖于类型参数test.getDays()时,<{1}}为什么不返回List<Integer> < / p>

当您创建一个对T实例的原始引用的变量时,编译器会丢弃所有泛型以通过该变量进行访问(为了向后兼容)。

由于Test未指定其类型test,这也意味着<T>的{​​{1}}将被丢弃。

答案 1 :(得分:3)

与Adel的答案略有不同,但你的意思是这个吗?

public class Test<T> {

public static void main(String[] args)
{
    Test<Integer> test = new Test<Integer>();

    Integer number = test.getDays().get(0);
}


private List<T> getDays() {
    return new ArrayList<T>();
}

} 

答案 2 :(得分:1)

试试这个:

public class Test<T> {

public static void main(String[] args)
{
    // using Test<?> solves the compilation error
    Test<Integer> test = new Test<Integer>();

    // getting error incompatible types:
    // found   : java.lang.Object
    // required: java.lang.Integer
    Integer number = test.getDays().get(0);
}


private List<Integer> getDays() {
    return new ArrayList<Integer>();
}

} 

答案 3 :(得分:1)

我试图编译它,我有同样的问题。我不认为OP想要解释如何使用泛型。自己尝试一下......奇怪的是它“应该”起作用,因为泛型类型T根本没有被使用,因为getDate的声明声明它将返回对整数列表的引用。 / p>

您可以像这样实例化测试:

Test<JFrame> test = new Test();

......它编译! (当然你可以在这里使用任何现有的类型...)奇怪的事情......

如果删除通用声明,它也可以(当然)。

答案 4 :(得分:0)

编译器无法确定Test的实际类型,因为您将其指定为泛型,然后使用原始类型。添加?通配符使编译器意识到实际的类只能在运行时确定;它不会检查班级类型。

您也可以通过使Test类非泛型或使getDays()返回List来解决编译。

答案 5 :(得分:0)

当您将变量或字段声明为原始类型时,该字段或变量的所有用法都会丢失所有通用信息,而不仅仅是与原始类型删除的类型变量相关的通用信息。这意味着,您对test.getDays()的调用返回了List而不是List<Integer>,即使整数与T无关。