Java:泛型强制转换生成警告,为什么?

Java:泛型强制转换生成警告,为什么?,java,generics,compiler-warnings,Java,Generics,Compiler Warnings,我不明白为什么下面的代码会生成警告 interface Generic<T> { } interface A { } class B { Generic<A> c; <T extends A> B(Generic<T> a) { c = (Generic<A>) a; //warning here } } //Unchecked cast from Generic<T> to

我不明白为什么下面的代码会生成警告

interface Generic<T> {
}

interface A {
}

class B {
    Generic<A> c;

    <T extends A> B(Generic<T> a) {
        c = (Generic<A>) a; //warning here
    }

}

//Unchecked cast from Generic<T> to Generic<A>
通用接口{
}
接口A{
}
B类{
通用c;
B(通用a){
c=(通用)a;//此处有警告
}
}
//从泛型到泛型的未选中强制转换
在B类中,我只对使用类型为A的泛型实例感兴趣。此警告建议我需要将泛型参数存储为T而不是A


但这意味着我也必须将B声明为泛型,这似乎使事情比它们需要的更复杂。

这不是向下转换,因为Java泛型是不变的:
generic
不是
generic
的子类型,即使T是a的子类型。如果您只需要返回a的泛型方法,您可以使用通配符
Generic,因为
Generic
不是
Generic
的子类型,即使
t
a
的子类型

为了说明这一点,考虑<代码> String < /Cult>实例<代码>对象< /代码>:

List<String> listOfStrings = new ArrayList<String>();
List<Object> listOfObjects = (List<Object>)listOfStrings; // invalid
listOfObjects.add(new Date());
// now listOfStrings contain a date!
List listofstring=new ArrayList();
列表对象列表=(列表)列表字符串;//无效的
添加(新日期());
//现在ListOfstring包含一个日期!
编译器不允许该强制转换,因为它可能导致原始列表损坏。JVM在运行时不强制执行通用边界要求

这里的解决方案是将字段
c
类型声明为
“泛型”。

如果不强制转换,会发生什么?java中泛型危险的经典示例