在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

在Java中,为什么参数化类型的构造函数的非类型化调用会引发编译器警告?为什么可以用静态方法做类似的事情?例如:

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()
    是正确的
  • 因为Java支持基于返回类型的自动类型推断,也就是说,它可以在这里暗示missign泛型参数,并且在方法内部,通过使用
    new Test()
    (而不仅仅是
    new Test()
    )对泛型类型进行了解释
  • 因为2.;-)
    Java对方法进行类型推断(这就是为什么第2行有效,第3行不必要),但对构造函数不进行类型推断(这就是为什么第1行给出警告)


    如果Java也对构造函数进行了类型推断,那就太好了,但从Java 6开始就没有了。

    我有一个与此相关的问题:关于第1点),是不是因为Task()等同于Task(),这意味着不安全的降级风险(例如,可以给Task添加一个数字)?@Matthias:no,并非完全如此——但出于所有实际意图和目的(生成的警告除外),它是<代码>任务仍然是显式键入的,而上面的不是。在运行时,由于类型擦除,它都解析为
    对象