我有一个父类 Builder
可以用 Builder
类型或其子类型的参数进行泛化:
class Builder<T extends Builder> {
@SuppressWarnings("unchecked")
T doSmth() {
System.out.println("do smth");
return (T)this;
}
}
它有一个子类 - BuilderChild
:
class BuilderChild extends Builder<BuilderChild> {
BuilderChild doSmthElse() {
System.out.println("do smth else");
return this;
}
}
因此,我可以在 BuilderChild
实例上调用方法 doSmth
并返回 BuilderChild
:
new BuilderChild().doSmth().doSmthElse();
但是当我尝试生成 BuilderChild
时,上面的行停止了编译。
class BuilderChild<T> extends Builder<BuilderChild> {
BuilderChild doSmthElse() {
System.out.println("do smth else");
return this;
}
}
...
//Compile error, because doSmth()
//returns Builder instead of BuilderChild.
new BuilderChild().doSmth().doSmthElse();
有人可以解释为什么 doSmth()
在我生成 BuilderChild
之后开始返回 Builder
吗?有什么办法可以解决吗?
最佳答案
问题是您使用的是 BuilderChild
作为原始类型。
这意味着它有类型参数,但您指定它而不提供任何类型参数。
这意味着几乎所有该类型的泛型信息都将被忽略(它是 a bit more complicated than that ,但这是高级 View )。
如果你这样写:
new BuilderChild<Object>().doSmth().doSmthElse();
然后编译。
此外,doSmthElse
应指定为 BuilderChild<T> doSmthElse()
.
请注意,支持原始类型只是为了向后兼容,不应在新代码中使用。
关于java - 泛化类和继承问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4470574/