首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有Java泛型的setParent(此)

带有Java泛型的setParent(此)
EN

Stack Overflow用户
提问于 2019-12-07 08:19:14
回答 3查看 210关注 0票数 3

我有一个泛型元素类,它包含同一个类的元素。基于此,我将创建如下所示的具体类

代码语言:javascript
复制
Boxes extends Element<Boxes>

我不明白的是

代码语言:javascript
复制
setParent(this); 

为什么我要投它

代码语言:javascript
复制
setParent((C) this); 

(并抑制类型转换警告)?显然我错过了什么..。如何将类更改为没有强制转换和警告?我认为“这”是一个元素对象(至少)和C。

代码语言:javascript
复制
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;
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-12-07 08:32:00

您会得到此错误,因为thisElement<C>类型,而不是C类型。

下列措施将起作用:

代码语言:javascript
复制
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很好地解释了你为什么会犯这样的错误。

票数 4
EN

Stack Overflow用户

发布于 2019-12-07 08:27:22

因为没有什么能保证this是C型的。

例如,您可以这样创建一个对象:

代码语言:javascript
复制
Element<Boxes> e = new Element<>();

或者这样:

代码语言:javascript
复制
class Container extends Element<Boxes> {}
...
Container c = new Container();
票数 4
EN

Stack Overflow用户

发布于 2019-12-07 11:17:20

您可以将protected abstract C self()方法添加到Element<C>类并使用它而不是(C) this

代码语言:javascript
复制
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

代码语言:javascript
复制
public class Boxes extends Element<Boxes> {
    @Override
    protected Boxes self() {
        return this;
    }
}

这是个很受欢迎的设计。例如,如果您使用Lombok 德隆伯克注释生成的德隆伯克构建器,您可以看到:

代码语言:javascript
复制
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);
        }
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59224202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档