在Java中,为什么参数化类型的构造函数的非类型化调用会引发编译器警告?
在Java中,为什么参数化类型的构造函数的非类型化调用会引发编译器警告?为什么可以用静态方法做类似的事情?例如:在Java中,为什么参数化类型的构造函数的非类型化调用会引发编译器警告?,java,generics,Java,Generics,在Java中,为什么参数化类型的构造函数的非类型化调用会引发编译器警告?为什么可以用静态方法做类似的事情?例如: class Test<T> { Test() {} static <T> Test<T> create() { return new Test<T>(); } @SuppressWarnings("unused") public static void main(String
class Test<T> {
Test() {}
static <T> Test<T> create() {
return new Test<T>();
}
@SuppressWarnings("unused")
public static void main(String[] args) {
Test<String> warning = new Test(); // compiler warning - why?
Test<String> okay = Test.create(); // no warning here - why?
Test<String> okay2 = Test.<String>create(); // why doesn't it need this?
}
}
类测试{
Test(){}
静态测试创建(){
返回新测试();
}
@抑制警告(“未使用”)
公共静态void main(字符串[]args){
Test warning=new Test();//编译器警告-为什么?
Test okay=Test.create();//此处没有警告-为什么?
Test okay2=Test.create();//为什么它不需要这个?
}
}
因为您将非类型化实例分配给类型化变量。您的三个案例:
newtest()
是正确的new Test()
(而不仅仅是new Test()
)对泛型类型进行了解释Java对方法进行类型推断(这就是为什么第2行有效,第3行不必要),但对构造函数不进行类型推断(这就是为什么第1行给出警告)
如果Java也对构造函数进行了类型推断,那就太好了,但从Java 6开始就没有了。我有一个与此相关的问题:关于第1点),是不是因为Task()等同于Task(),这意味着不安全的降级风险(例如,可以给Task添加一个数字)?@Matthias:no,并非完全如此——但出于所有实际意图和目的(生成的警告除外),它是<代码>任务仍然是显式键入的,而上面的不是。在运行时,由于类型擦除,它都解析为
对象
。