编译警告:未经检查的对 XXX 作为原始类型成员的调用

Compilation warning: Unchecked call to XXX as member of the raw type

我收到编译器警告:

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

AbstractPresenterclass的代码如下:

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

下面AbstractViewclass中调用了setView方法:

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

我搜索了其他成员关于相同警告的问题,并尝试调整解决方案以适应我的问题,但没有奏效。

我不明白为什么在 AbstractPresenter class:

的声明中强制使用 V 类型时会引发警告
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 被声明为扩展 raw AbstractPresenter 的类型。基本上,我们不知道那个类型的VM是什么。

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

也是如此
public abstract class AbstractPresenter<V extends AbstractView, M> 

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

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

我本来想添加评论但不能,因为我没有足够的声誉。

你的类型是原始的。 AbstractView 中的呈现器是原始类型,因为传递给抽象视图的通用参数是原始的