Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get "circular" generics working in Java?

I am having an error while compiling the following code involving a few generics:

public abstract class State<T extends HasAState<? extends State<T>>>{
    protected T parent;

    public void setParent(){ // It's been simplified for the sake of the question!
        parent.removeState(this); // Error here!
        this.parent = parent;
        parent.addState(this);    // Error here!
    }
}

public interface HasAState<T extends State<? extends HasAState<T>>> {
    public void addState(T state);
    public void removeState(T state);
}

The errors are: The method removeState(capture#1-of ? extends State<T>) in the type HasAState<capture#1-of ? extends State<T>> is not applicable for the arguments (State<T>)

Actually what I would like to have is something like: class A implements HasAState and class B extends State<A> where B has a reference to A and can call A.addState(B) (only because B extends State<A>) and where A can call B.setParent(this).

How should I declare my classes so that what I intend to do work?

Thanks

like image 588
Jean Logeart Avatar asked Jul 24 '26 15:07

Jean Logeart


1 Answers

I agree with the comment of Eran Zimmerman. It seams that you need to rethink about what you want.

Anyway I hope I have understand the problem right, so I changed the Parameter from one to tow, to describe the state and the hasAState separately.

public abstract class State<S extends State<S, H>, H extends HasAState<S, H>>{
    protected H parent;

    public void setParent(){ 
        parent.removeState(this);
        this.parent = parent; //!!!this line has no effect!!!
        parent.addState(this);        
    }       
}

public interface HasAState<S extends State<S, H>, H extends HasAState<S, H>> {
    public void addState(State<S, H> state);
    public void removeState(State<S, H> state);
}

This code compiles! -- be aware of the warning for the second line in setParent.

like image 96
Ralph Avatar answered Jul 27 '26 11:07

Ralph



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!