我有一个父类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;
}
}
因此,我可以在
doSmth
实例上调用方法BuilderChild
并返回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()
后Builder
开始返回BuilderChild
吗?有什么办法可以解决? 最佳答案
问题是您将BuilderChild
用作原始类型。
这意味着它具有类型参数,但是您在不提供任何类型参数的情况下指定了它。
这意味着几乎所有该类型的泛型信息都将被忽略(它是a bit more complicated than that,但这是高级视图)。
如果您改写以下代码:
new BuilderChild<Object>().doSmth().doSmthElse();
然后编译。
另外,
doSmthElse
应指定为BuilderChild<T> doSmthElse()
。请注意,仅支持原始类型是为了向后兼容,而不应在新代码中使用。