我有一个如下给出的方法,它给了我编译时错误。
class Parent {
public abstract <T extends Parent> T copy();
}
在子类中
class Child extends parent{
public <T extends Parent> T copy() {
return new Child();
}
}
通过泛型,我告诉类型橡皮擦我将返回子对象,但它不允许我这样做。 有人对此有意见/解决方案吗?
我可以用下面给出的新方法解决我的问题。
class Parent {
public Parent copy(){
//some stuff
}
}
class Child extends Parent{
@Override
public Child copy(){
Child c = (Child) super.copy();//I want to avoid this type casting here.
}
}
所以上面的方法解决了我的问题,但是如果我想使用父类复制方法并且另外想在子类中做更多的事情,我必须在子类中进行 TYPE CAST 。
那么考虑两者,你有更好的方法来解决问题吗?
最佳答案
问题是,当您以这种方式声明方法时,您的通用参数不会绑定(bind)到任何东西。编译器为 T 绑定(bind)类型的唯一方法是在调用该方法的行中。例如,它将在以下调用中假定类型为 Child:
Child c = copy();
现在,如果编译器认为您的代码合法,并且您执行了如下操作,会发生什么情况?
GrandChild g = copy();
在这种情况下,您将在运行时遇到意外的 ClassCastException,而这正是泛型试图避免的。
请注意,即使您按照其他人的建议强制转换为 T,您也会收到编译器警告,因为风险仍然存在。
以下替代方案在类型安全方面更好,但有点麻烦:
abstract class Parent<T extends Parent<T>> {
public abstract T copy();
}
class Child extends Parent<Child> {
public Child copy() {
return new Child();
}
}
关于Java 泛型方法的行为不符合预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20738553/