我可以像这样声明类:
class TestClass<K extends TestClass<K>> {
}
我需要一个返回K
类型的方法:
class TestClass<K extends TestClass<K>> {
K getK() {
}
}
如果我返回类实例:
class TestClass<K extends TestClass<K>> {
K getK() {
return this;
}
}
我有关于不兼容类型的错误。
当然,我可以做演员:
class TestClass<K extends TestClass<K>> {
K getK() {
return (K) this;
}
}
但在这种情况下,我发出了关于未经检查的演员的警告。
有没有办法在没有警告抑制的情况下做到这一点?
修改 我真正想做的事 - 拥有这两个课程:
class BaseViewHolder<T extends BaseViewHolder<T, K>, K extends BaseViewModel<T, K>> {
K model;
void setModel(K model) {
this.model = model;
model.setHolder((T) this);
}
}
和
class BaseViewModel<T extends BaseViewHolder<T, K>, K extends BaseViewModel<T, K>> {
T holder;
void setHolder(T holder) {
this.holder = holder;
}
}
我希望每个具体的ViewModel都知道相应的具体ViewHolder,并且每个具体的ViewHolder都知道相应的具体ViewModel。
这就是为什么我想拥有这样的结构。 实际上,我没有找到另一种方式来告诉BaseModel关于持有者而不是上面的内容。
答案 0 :(得分:4)
声明类似泛型的类不会使该类成为K的实例。您没有扩展K.您的演员阵容不仅未经检查,而且是错误的。
考虑一下这个例子:
public static void main(String[] args) throws InterruptedException {
new TestClass<AnotherClass>().getK().get0();
}
class AnotherClass extends TestClass<AnotherClass>{
int get0() {
return 0;
}
}
class TestClass<K extends TestClass<K>> {
K getK() {
return (K)this;
}
}
这会导致运行时异常:
线程“main”中的异常java.lang.ClassCastException:TestClass 不能转换为AnotherClass
基本上当你cast (K)
这个时,你正在将一个TestClass类型的对象转换为一个扩展TestClass的对象。另一种方法是真的--K是TestClass,但TestClass不是K。
修改强>
我看到了你的问题,但仍然是演员阵容不正常。你不知道你将获得什么样的BaseViewHolder实现/子类,以及在使用时指向特定类型的泛型。 K是BaseViewHolder的子代,并将任何BaseViewHolder强制转换为K,这是一个特定的子类是不正确的。
你为什么不这样做:
class BaseViewModel {
BaseViewHolder holder;
//You can call this setter with any subclass of BaseViewHolder without casting!
void setHolder(BaseViewHolder holder) {
this.holder = holder;
}
}
class BaseViewHolder {
BaseViewModel model;
//You can call this setter with any subclass of BaseViewModel without casting!
void setModel(BaseViewModel model) {
this.model = model;
model.setHolder( this);
}
}
我看不出有任何理由在你的情况下使用泛型。使它成为可以扩展BaseViewHolder和BaseViewModel并使用子类作为基类的实例而没有任何问题。