编译警告:未选中调用XXX作为原始类型的成员

jco*_*.be 17 java generics unchecked compiler-warnings

我收到编译器警告:

警告:[unchecked] unchecked调用setView(V)作为原始类型AbstractPresenter的成员

   this.presenter.setView(this);
Run Code Online (Sandbox Code Playgroud)

其中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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经搜索了其他成员关于相同警告的问题,并试图使解决方案适应我的问题,但它没有奏效.

我不明白为什么会引发警告,因为在V类的声明中强制类型AbstractPresenter:

public abstract class AbstractPresenter<V extends AbstractView, M> 
implements Presenter<V, M> 
Run Code Online (Sandbox Code Playgroud)

这只是一个警告,我可以忽略它,但我想了解它为什么会发生,我想让我的代码尽可能干净.

Boh*_*ian 9

你的类型是原始的 - 也就是说,你的泛型类型绑定到一个本身有类型的类型,但是你没有提供类型,所以它是原始的.

更改要键入的类型边界.试试这个:

public abstract class AbstractPresenter<V extends AbstractView<V>, M> implements Presenter<V, M>
Run Code Online (Sandbox Code Playgroud)

public abstract class AbstractView<P extends AbstractPresenter<P> extends UserControl
Run Code Online (Sandbox Code Playgroud)

  • 我无法检查几个答案,所以我检查了一个,但所有的贡献帮助我解决了我的问题,所以感谢所有人在这个线程. (3认同)

Rea*_*tic 7

你的问题在于这一行:

public abstract class AbstractView<P extends AbstractPresenter> extends
Run Code Online (Sandbox Code Playgroud)

P被声明为扩展原始 类型的类型AbstractPresenter.基本上,我们不知道是什么V以及M该类型是.

因此this.presenter是这种原始类型,我们不知道它VM.因此,当您调用它setViewthis,编译器无法判断类型是否正确.

同样如此

public abstract class AbstractPresenter<V extends AbstractView, M> 
Run Code Online (Sandbox Code Playgroud)

V是一种扩展raw 的类型,AbstractView我们不知道它的基本类型是什么.因此编译器无法完成泛型的工作.

每当您进行此类型声明时,请记住在声明中指定所有泛型类型的类型,并使用正确表示它们之间关系的类型变量.