web-dev-qa-db-ja.com

コンパイルの警告:生の型のメンバーとしてのXXXへの未チェックの呼び出し

コンパイラの警告が表示されます。

警告:[未チェック]生のタイプAbstractPresenterのメンバーとしてのsetView(V)の未チェックの呼び出し

   this.presenter.setView(this);

ここで、Vは型変数です。

Vは、クラスAbstractPresenterで宣言されたAbstractViewを拡張します

AbstractPresenterクラスのコードは次のとおりです。

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

setViewメソッドは、以下のAbstractViewクラスで呼び出されます。

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

同じ警告に関する他のメンバーからの質問を検索し、解決策を私の問題に適合させようとしましたが、うまくいきませんでした。

Vクラスの宣言でAbstractPresenter型が強制されるため、警告が発生する理由がわかりません。

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

それは単なる警告であり、私はそれを無視することができますが、なぜそれが起こるのかを理解したいので、コードをできるだけきれいにしたいです。

17
jcollin.be

あなたの型は生です-つまり、あなたのジェネリック型はそれ自身が型を持つ型に結合されていますが、あなたはそれを提供していないので、それは生です。

入力するタイプ境界を変更します。これを試して:

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

そして

public abstract class AbstractView<P extends AbstractPresenter<P> extends UserControl
9
Bohemian

問題は次の行にあります。

public abstract class AbstractView<P extends AbstractPresenter> extends

Pは、rawAbstractPresenterを拡張する型として宣言されます。基本的に、そのタイプのVおよびMが何であるかはわかりません。

したがって、this.presenterはこの生のタイプであり、そのVMがわかりません。したがって、setViewthisを呼び出すと、コンパイラは型が正しいかどうかを判断できません。

同じことが当てはまります

public abstract class AbstractPresenter<V extends AbstractView, M> 

VrawAbstractViewを拡張する型であり、その基本型がわからない。したがって、コンパイラはジェネリックが意図された作業を実行できません。

このような型宣言を行う場合は、必ず宣言ですべてのジェネリック型の型を指定し、それらの間の関係を正しく表す型変数を使用することを忘れないでください。

7
RealSkeptic

コメントを追加したかったのですが、評判がよくなかったのでできませんでした。

あなたのタイプは生です。 AbstractViewに渡されるジェネリックパラメーターはrawであるため、AbstractViewのプレゼンターはrawタイプです。

2