17

I am getting the compiler warning:

warning: [unchecked] unchecked call to setView(V) as a member of the raw type AbstractPresenter

   this.presenter.setView(this);

where V is a type-variable:

V extends AbstractView declared in class AbstractPresenter

The code of the AbstractPresenter class is the following:

public abstract class AbstractPresenter<V extends AbstractView, M> 
implements Presenter<V, M> {

    private M model;
    private V view;

    @Override
    public final V getView() {
        return this.view;
    }

    public final void setView(V view) {
        if (view == null) {
            throw new NullPointerException("view cannot be null.");
        }

        if (this.view != null) {
            throw new IllegalStateException("View has already been set.");
        }
        this.view = view;
    }

    @Override
    public final M getModel() {
        return this.model;
    }

    protected final void setModel(M model) {
        if (model == null) {
            throw new NullPointerException("model cannot be null.");
        }        
        this.model = model;
    }
}

The setView method is called in the AbstractView class below:

public abstract class AbstractView<P extends AbstractPresenter> extends 
UserControl {
    private final P presenter;

    public AbstractView(P presenter) {
        this.presenter = presenter;
        this.initialisePresenter();
    }

    private void initialisePresenter() {
        if (this.presenter == null){
            throw new IllegalStateException();
        }

        this.presenter.setView(this); //This is the call that raises the warning
    }

    protected P getPresenter() {
        return this.presenter;
    }
}

I have searched the questions from other members regarding the same warning and tried to adapt the solutions to my issue but it did not work.

I don't understand why the warning is raised as the V type is forced in the declaration of the AbstractPresenter class:

public abstract class AbstractPresenter<V extends AbstractView, M> 
implements Presenter<V, M> 

It is just a warning and I could ignore it but I would like to understand why it happens and I want to get my code as clean as possible.

Lii
  • 11,553
  • 8
  • 64
  • 88
jcollin.be
  • 300
  • 1
  • 2
  • 6
  • The cyclic references in your code are giving me a headache. Why does view need to have a presenter and why does presenter in turn need to have a view? Can't you convert this to a one way relationship? – Chetan Kinger Jun 13 '15 at 07:31
  • 1
    http://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it – kervin Jun 13 '15 at 08:18
  • @Chetan Kniger and Kervin Thank you both, now I know what is a raw type and indeed I have a cyclic references which will transform into circular inheritance if I parametrize the declaration of V in the AbstractPresenter class... So I need to go back to the design part. I think the View does not need to reference the Presenter here. – jcollin.be Jun 13 '15 at 17:00

3 Answers3

9

Your types are raw - that is, your generic types are bonded to a type that itself has a type, but you haven't provided one, so it's raw.

Change your type bounds to be typed. Try this:

public abstract class AbstractPresenter<V extends AbstractView<V>, M> implements Presenter<V, M>

and

public abstract class AbstractView<P extends AbstractPresenter<P> extends UserControl
Chetan Kinger
  • 15,069
  • 6
  • 45
  • 82
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 3
    I cannot check several answers so I checked that one but all contributions helped me solving my issue so thanks to all in this thread. – jcollin.be Jun 13 '15 at 17:42
7

Your problem is with this line:

public abstract class AbstractView<P extends AbstractPresenter> extends

Your P is declared as a type that extends a raw AbstractPresenter. Basically, we don't know what the V and M of that type is.

Therefore this.presenter is of this raw type and we don't know its V and M. Thus when you call its setView with this, the compiler cannot tell whether the types are correct or not.

The same is true for

public abstract class AbstractPresenter<V extends AbstractView, M> 

V is a type that extends a raw AbstractView and we don't know what the base type of it is. Thus the compiler cannot do the work for which generics were meant.

Whenever you make such type declarations, remember to specify the types of all generic types in the declaration, and use type variables that correctly represent the relationships between them.

RealSkeptic
  • 33,993
  • 7
  • 53
  • 79
2

I had wanted to add a comment but could not as i dont have enough reputation.

your types are raw. the presenter in AbstractView is raw type as the generic parameters passed to Abstract View is raw