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()returnList
当您创建一个对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
。因此,如果您在类中删除
,编译器将假定您希望在预泛型模式下使用它,并删除所有其他
。