コンパイラの警告が表示されます。
警告:[未チェック]生のタイプ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>
それは単なる警告であり、私はそれを無視することができますが、なぜそれが起こるのかを理解したいので、コードをできるだけきれいにしたいです。
あなたの型は生です-つまり、あなたのジェネリック型はそれ自身が型を持つ型に結合されていますが、あなたはそれを提供していないので、それは生です。
入力するタイプ境界を変更します。これを試して:
public abstract class AbstractPresenter<V extends AbstractView<V>, M> implements Presenter<V, M>
そして
public abstract class AbstractView<P extends AbstractPresenter<P> extends UserControl
問題は次の行にあります。
public abstract class AbstractView<P extends AbstractPresenter> extends
P
は、rawAbstractPresenter
を拡張する型として宣言されます。基本的に、そのタイプのV
およびM
が何であるかはわかりません。
したがって、this.presenter
はこの生のタイプであり、そのV
とM
がわかりません。したがって、setView
でthis
を呼び出すと、コンパイラは型が正しいかどうかを判断できません。
同じことが当てはまります
public abstract class AbstractPresenter<V extends AbstractView, M>
V
はrawAbstractView
を拡張する型であり、その基本型がわからない。したがって、コンパイラはジェネリックが意図された作業を実行できません。
このような型宣言を行う場合は、必ず宣言ですべてのジェネリック型の型を指定し、それらの間の関係を正しく表す型変数を使用することを忘れないでください。
コメントを追加したかったのですが、評判がよくなかったのでできませんでした。
あなたのタイプは生です。 AbstractViewに渡されるジェネリックパラメーターはrawであるため、AbstractViewのプレゼンターはrawタイプです。