abstract class AbsClass {}
class MyAbs extends AbsClass {}
class MyClass<S extends AbsClass> {
S getObj() {
return new MyAbs();
}
}
Run Code Online (Sandbox Code Playgroud)
获取编译器问题:
错误:(33,16)java:不兼容的类型:MyAbs无法转换为S.
这样做的正确方法是什么?
编辑:我希望能够初始化MyClass {MyAbs},然后调用getObj(),这将返回一个MyAbs对象.有了Andy的回答,我必须将AbsClass转换为MyAbs或MySecondAbs,这是我试图避免的
安迪已经描述了如何解决问题,我将尝试解释原因.
S
不保证可以分配给MyAbs
,只有AbsClass
,并且每个实例都会指定一个子类AbsClass
.
考虑:
class MyOtherAbs extends AbsClass {}
MyClass myClass = new MyClass<MyOtherAbsClass>{};
Run Code Online (Sandbox Code Playgroud)
这会与你所拥有的相冲突.
更新:
根据您的评论,您希望实现上述目标.挑战是如果MyOtherAbs
有一个带参数的构造函数?或者实现为Singleton(即私有构造函数和静态getInstance()
).简而言之,没有保证统一的方法可以构建这些.此外,由于类型擦除,在运行时,S的概念消失了,所以你不能做类似的事情:
return new S();
Run Code Online (Sandbox Code Playgroud)
你基本上有两个选择,一个是使用子类:
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
}
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是反思:
class MyClass {
public <S extends AbsClass> S getObj(Class<S> clazz) throws InstantiationException, IllegalAccessException {
return clazz.newInstance();
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,第二个假设没有可用的arg构造函数,如果不是,则会抛出运行时异常.
归档时间: |
|
查看次数: |
2134 次 |
最近记录: |