Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

setParent(this) with Java generics

Tags:

java

generics

I have a generic Element class which contains elements of the same class. Based on that I would then create concrete classes like

Boxes extends Element<Boxes>

The point I don't get is the

setParent(this); 

Why do I need to cast it

setParent((C) this); 

(and suppress type casting warnings)? Obviously I am missing something... How would you change the class to have no casting and no warnings? I would argue that "this" is a Element object (at minimum) and C as well.

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;
}
like image 236
Werner Daehn Avatar asked Feb 17 '26 15:02

Werner Daehn


2 Answers

You get this error because this is of type Element<C> and not of type C.

The following would work:

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;
    }
}

Btw, IDEs are pretty good explaining why you get such errors.

like image 143
Puce Avatar answered Feb 19 '26 05:02

Puce


Because nothing guarantees that this is of type C.

For example, you could create an object this way:

Element<Boxes> e = new Element<>();

or this way:

class Container extends Element<Boxes> {}
...
Container c = new Container();
like image 33
JB Nizet Avatar answered Feb 19 '26 06:02

JB Nizet