Java IntelliJ中具有泛型类型的未选中转换警告
My IDE(IntelliJ)警告我未经检查的转换: 未经检查的覆盖:返回类型需要未经检查的转换。找到'com.company.Main.Cat',必需'T' 尽管如此,我的代码还是像预期的那样工作。我能做些什么来防止这个警告,还是我的代码有“设计”缺陷 以下MCVE再现了Java IntelliJ中具有泛型类型的未选中转换警告,java,generics,Java,Generics,My IDE(IntelliJ)警告我未经检查的转换: 未经检查的覆盖:返回类型需要未经检查的转换。找到'com.company.Main.Cat',必需'T' 尽管如此,我的代码还是像预期的那样工作。我能做些什么来防止这个警告,还是我的代码有“设计”缺陷 以下MCVE再现了Cat的public Cat copy()中的警告 public static void main( String[] args ) { Cat cat = new Cat( "Mimi&q
Cat
的public Cat copy()
中的警告
public static void main( String[] args )
{
Cat cat = new Cat( "Mimi" );
Cat copyCat = cat.copy();
}
public static class Cat extends Animal
{
public String name;
public Cat( final String name )
{
this.name = name;
}
@Override
public Cat copy() // Unchecked conversion warning
{
return new Cat( this.name );
}
}
public abstract static class Animal
{
abstract < T extends Animal > T copy();
}
publicstaticvoidmain(字符串[]args)
{
猫=新猫(“咪咪”);
Cat copyCat=Cat.copy();
}
公共静态类猫扩展动物
{
公共字符串名称;
公共Cat(最终字符串名称)
{
this.name=名称;
}
@凌驾
public Cat copy()//未检查的转换警告
{
返回新的Cat(this.name);
}
}
公共抽象静态类动物
{
抽象T拷贝();
}
你的动物。copy
方法是泛型的,建议调用者可以指定他们想要的动物类型。。。但您的实现不是通用的
例如,这里有一个稍微增加和更改的代码版本-注意对main
方法的更改,该方法仅使用Animal
作为变量类型,但为copy
方法指定了一个类型参数:
公共类测试{
公共静态void main(字符串[]args){
动物猫=新猫(“咪咪”);
Dog copyCat=cat.copy();
}
公共静态类猫扩展动物{
公共字符串名称;
公共Cat(最终字符串名称){
this.name=名称;
}
@凌驾
公共Cat副本(){
返回新的Cat(this.name);
}
}
公共抽象静态类Dog扩展了Animal{
}
公共抽象静态类动物{
抽象T拷贝();
}
}
main
方法在没有警告的情况下编译-很好
但在执行时:
Exception in thread "main" java.lang.ClassCastException: Test$Cat cannot be cast to Test$Dog
at Test.main(Test.java:6)
因此,是的,您的代码存在设计缺陷,并且只在您开始使用的用例中按预期工作。几乎可以肯定的是,您不希望使该方法成为泛型方法。您可以将类设置为泛型,也可以将抽象的copy
方法声明为returningAnimal
:
公共抽象静态类动物{
抽象动物复制();
}
现在,这将允许声明
Dog.copy()
返回Cat
,当然。。。但是它至少很简单。如果您想要一个通用的copy()
方法以您所期望的方式工作,我会这样更改两个类:
public abstract static class Animal<T extends Animal> {
abstract T copy();
}
public static class Cat extends Animal<Cat> {
public String name;
public Cat(final String name) {
this.name = name;
}
@Override
public Cat copy() {
return new Cat(this.name);
}
}
没关系。然后,参数的编译时类型告诉编译器预期的结果,并且可以(例如,使用clone()
)实现一个方法,该方法返回作为其参数得到的同一类的实例
但是用这样的方法
public <T extends Animal> T copy(T originalAnimal) { ... }
public <T extends Animal> T copy() { ... }
public T copy(){…}
编译器已经很难确定T
类型(有时可以从赋值到的变量中确定,也可以提供
类型中缀)
但更重要的是,您不知道运行时的t
类型,并且在方法实现中也没有任何可用的信息,无论t
是否以某种方式绑定到Cat
、Dog
或其他什么。因此,您无法实现遵循此签名的方法
经验法则:比起类,更喜欢泛型类型参数。感谢您的进一步澄清,我最终按照您的建议实现了类的泛型类型。在我努力理解确定泛型方法的T类型的问题之前。