Java 奇怪的仿制药问题

Java 奇怪的仿制药问题,java,generics,compiler-construction,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 :

有人知道为什么下面的代码没有编译,在编译过程中我得到了不兼容的异常类型吗

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>();
}
公共类测试{
公共静态void main(字符串[]args)
{
//使用Test解决编译错误
测试=新测试();
//获取错误不兼容类型:
//找到:java.lang.Object
//必需:java.lang.Integer
整数=test.getDays().get(0);
}
私有列表getDays(){
返回新的ArrayList();
}
}

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

尝试以下方法:

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>();
}

} 
公共类测试{
公共静态void main(字符串[]args)
{
//使用Test解决编译错误
测试=新测试();
//获取错误不兼容类型:
//找到:java.lang.Object
//必需:java.lang.Integer
整数=test.getDays().get(0);
}
私有列表getDays(){
返回新的ArrayList();
}
} 

与阿德尔的答案略有不同,但你的意思是这样的吗

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>();
}

} 
公共类测试{
公共静态void main(字符串[]args)
{
测试=新测试();
整数=test.getDays().get(0);
}
私有列表getDays(){
返回新的ArrayList();
}
} 

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


您还可以通过使测试类非泛型或使getDays()返回一个列表来解决编译问题。

我试图编译它,但遇到了相同的问题。我认为OP不需要解释如何使用泛型。你自己试试看。。。奇怪的是它“应该”工作,因为根本没有使用泛型类型T,因为getDate声明它将返回对整数列表的引用

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

Test<JFrame> test = new Test();
Test Test=新测试();
。。。它编译了!(当然你可以在这里使用任何现有的类型…)奇怪的事情


如果删除泛型声明,它也会起作用(当然)。

我将问题解释为当返回类型不依赖于类型参数时,
t
为什么不测试.getDays()return
List

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


因为
test
没有指定其类型
,这也意味着
getDays
被丢弃。

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

如果无法回答您的问题,我可以告诉您,永远不要使用原始类型。所以Test=new Test()是一个坏习惯。在以后的Java版本中将禁止IIRC使用原始类型。“公共类测试”能为您带来什么?另外,为什么“Test Test=new Test()”是一个坏习惯(原始类型?)?感谢您的澄清。(通常的评论是Oracle JRE 6的最新安全版本是1.6.0_20(又称6u20)。)重点是:泛型类型不应该打扰编译器,因为getDays声明它将返回一个整数列表(无论t设置为什么类型),谢谢!你能举一个这样做可以解决的向后兼容性问题的例子吗?在Java 1.5之前,你不能使用
List
你必须使用
List
。因此,如果您在类中删除
,编译器将假定您希望在预泛型模式下使用它,并删除所有其他