我有一个泛型元素类,它包含同一个类的元素。基于此,我将创建如下所示的具体类
Boxes extends Element<Boxes>我不明白的是
setParent(this); 为什么我要投它
setParent((C) this); (并抑制类型转换警告)?显然我错过了什么..。如何将类更改为没有强制转换和警告?我认为“这”是一个元素对象(至少)和C。
public class Element<C extends Element<C>> {
List<C> children;
C parent = null;
public Element() {
}
void setChildren(List<C> children) {
this.children = children;
for (C c : children) {
c.setParent((C) this); // warning, without the cast: error
}
}
void setParent(C parent) {
this.parent = parent;
}发布于 2019-12-07 08:32:00
您会得到此错误,因为this是Element<C>类型,而不是C类型。
下列措施将起作用:
public class Element<C extends Element<C>> {
List<C> children;
Element<C> parent = null;
public Element() {
}
void setChildren(List<C> children) {
this.children = children;
for (C c : children) {
c.setParent(this);
}
}
void setParent(Element<C> parent) {
this.parent = parent;
}
}顺便说一句,IDE很好地解释了你为什么会犯这样的错误。
发布于 2019-12-07 08:27:22
因为没有什么能保证this是C型的。
例如,您可以这样创建一个对象:
Element<Boxes> e = new Element<>();或者这样:
class Container extends Element<Boxes> {}
...
Container c = new Container();发布于 2019-12-07 11:17:20
您可以将protected abstract C self()方法添加到Element<C>类并使用它而不是(C) this。
public abstract class Element<C extends Element<C>> {
List<C> children;
C parent = null;
protected abstract C self();
void setChildren(List<C> children) {
this.children = children;
for (C c : children) {
c.setParent(self());
}
}
void setParent(C parent) {
this.parent = parent;
}
}现在扩展Element<C>时,只需返回this就可以实现this
public class Boxes extends Element<Boxes> {
@Override
protected Boxes self() {
return this;
}
}这是个很受欢迎的设计。例如,如果您使用Lombok 德隆伯克注释生成的德隆伯克构建器,您可以看到:
public class Example {
private final int someField;
protected Example(ExampleBuilder<?, ?> b) {
this.someField = b.someField;
}
public static ExampleBuilder<?, ?> builder() {
return new ExampleBuilderImpl();
}
public static abstract class ExampleBuilder<C extends Example, B extends ExampleBuilder<C, B>> {
private int someField;
public B someField(int someField) {
this.someField = someField;
return self();
}
protected abstract B self();
public abstract C build();
public String toString() {
return "Example.ExampleBuilder(someField=" + this.someField + ")";
}
}
private static final class ExampleBuilderImpl extends ExampleBuilder<Example, ExampleBuilderImpl> {
protected Example.ExampleBuilderImpl self() {
return this;
}
public Example build() {
return new Example(this);
}
}
}https://stackoverflow.com/questions/59224202
复制相似问题