abstract class AbsClass {}
class MyAbs extends AbsClass {}
class MyClass<S extends AbsClass> {
S getObj() {
return new MyAbs();
}
}
获取编译器问题:
Error:(33, 16) java: incompatible types: MyAbs cannot be converted to S
正确的做法是什么?
编辑: 我希望能够初始化 MyClass{MyAbs} 然后调用 getObj() 返回一个 MyAbs 对象。根据 Andy 的回答,我必须将 AbsClass 转换为 MyAbs 或 MySecondAbs,这是我试图避免的
最佳答案
Andy 已经描述了如何解决这个问题,我将尝试解释原因。
S
不保证可以分配给MyAbs
,只能分配给AbsClass
,每个实例都会指定一个AbsClass的子类
。
考虑:
class MyOtherAbs extends AbsClass {}
MyClass myClass = new MyClass<MyOtherAbsClass>{};
这会与您拥有的冲突。
更新:
根据您的评论,您似乎想要实现上述目标。挑战是如果 MyOtherAbs
有一个带参数的构造函数怎么办?或者作为单例实现(即私有(private)构造函数和静态 getInstance()
)。简而言之,没有保证可以构建这些的统一方法。此外,由于类型删除,在运行时,S 的概念消失了,所以你不能做这样的事情:
return new S();
基本上有两种选择,一种是使用子类化:
public interface AbsClassFactory<S extends AbsClass>{ //takes the place of MyClass
public S getInstance();
}
MyAbsFactory implements AbsClassFactory<MyAbs>{
public MyAbs getInstance(){
return new MyAbs(); //or however MyAbs is instantiated
}
}
另一种选择是反射:
class MyClass {
public <S extends AbsClass> S getObj(Class<S> clazz) throws InstantiationException, IllegalAccessException {
return clazz.newInstance();
}
}
请注意,第二个假设没有可用的 arg 构造函数,如果没有则抛出运行时异常。
关于使用 <S extends {class}> 的 Java 泛型和不兼容类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40516423/