Java 为什么泛型中的未指定类型会破坏非泛型方法的类型安全性

Java 为什么泛型中的未指定类型会破坏非泛型方法的类型安全性,java,generics,Java,Generics,有人能解释一下,为什么我的接口中一个简单的会在编译时破坏类型安全性?请参见以下示例: public类GenericsMain{ 公共静态void main(字符串[]args){ A someA=新的A(){ @凌驾 公共列表列表字符串(){ 返回数组。asList(“A”); } }; B someB=新的B(){ @凌驾 公共列表列表字符串(){ 返回数组。asList(“B”); } }; List listOfLong=null; //listOfLong=someA.listOfStr

有人能解释一下,为什么我的接口中一个简单的
会在编译时破坏类型安全性?请参见以下示例:

public类GenericsMain{
公共静态void main(字符串[]args){
A someA=新的A(){
@凌驾
公共列表列表字符串(){
返回数组。asList(“A”);
}
};
B someB=新的B(){
@凌驾
公共列表列表字符串(){
返回数组。asList(“B”);
}
};
List listOfLong=null;
//listOfLong=someA.listOfStrings();//编译错误(预期)
listOfLong=someB.listOfStrings();//没有编译错误。为什么!?
对于(长l:listOfLong){//这里我当然得到了一个例外。
系统输出打印LN(l);
}
}
接口A{
列出listOfStrings();
}
接口B{
列出listOfStrings();
}
}
同样有趣的是,如果指定了
的类型,编译器会再次正确地进行投诉。看来泛型也会影响非泛型方法声明

B someBOfInteger=null;
listOfLong=someBOfInteger.listOfStrings();//编译器正确地抱怨
回答正确后更新: 因此,如果需要使用泛型扩展类型,最好创建一个子类/子接口,并在子类中添加泛型类型。因此,在上面的示例中,可以通过

接口C扩展了{
T-一般方法(tp);
}
同样如参考问题所示,最好使用编译器标志:

javac -Xlint:unchecked ....

你会发现答案是

构造函数(§8.8)、实例方法(§8.8、§9.4)或非静态字段(§8.3)的类型未从其超类或超接口继承的原始类型C的M是在对应于C的泛型声明中删除其类型。原始类型C的静态成员的类型与对应于C的泛型声明中的类型相同

如果创建泛型类的实例而不为其指定泛型类型,则它将成为原始类型。而且,由于JLS的该部分,其所有(非继承的)字段也将被擦除。因此,您将接口声明为:

interface B{
    List listOfStrings();
}

这导致了您看到的错误。被返回的
列表的泛型类型将被删除,即使您明确指定了它。这就是为什么应始终避免使用原始类型的原因之一。

当您使用原始
B
时,即使与
无关,也会忽略所有常规信息。这个问题有一个合适的副本。。。“正在查找它。@汤姆:我认为问题是一样的,但问题是关于启用-Xlint:unchecked编译器标志的编译器警告。”。事实上,在编译时检测这些问题是一件好事。关于重复问题:不要太关注问题本身,重要的部分是答案(如果有几个答案,那么“是答案”)。如果他们也回答了您的问题,那么这是一个合适的副本:)。