Предупреждение о компиляции: непроверенный вызов на XXX в качестве члена необработанного типа
Я получаю предупреждение компилятора:
предупреждение: [unchecked] unchecked вызов setView (V) в качестве члена необработанного типа AbstractPresenter
this.presenter.setView(this);
где V - переменная типа:
V расширяет AbstractView, объявленный в классе AbstractPresenter
Код класса 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>
Это просто предупреждение, и я мог бы игнорировать его, но я хотел бы понять, почему это происходит, и я хочу, чтобы мой код был как можно более чистым.
Ответы
Ответ 1
Ваши типы являются сырыми - то есть ваши общие типы привязаны к типу, который сам имеет тип, но вы его не предоставили, поэтому он необработанный.
Измените ограничения типа, которые нужно ввести. Попробуйте следующее:
public abstract class AbstractPresenter<V extends AbstractView<V>, M> implements Presenter<V, M>
и
public abstract class AbstractView<P extends AbstractPresenter<P> extends UserControl
Ответ 2
Ваша проблема в этой строке:
public abstract class AbstractView<P extends AbstractPresenter> extends
Ваш P
объявлен как тип, который расширяет raw AbstractPresenter
. В принципе, мы не знаем, что такое V
и M
этого типа.
Поэтому this.presenter
относится к этому необработанному типу, и мы не знаем его V
и M
. Таким образом, когда вы вызываете его setView
с помощью this
, компилятор не может определить, являются ли типы правильными или нет.
То же самое верно для
public abstract class AbstractPresenter<V extends AbstractView, M>
V
- это тип, который расширяет raw AbstractView
, и мы не знаем, каков его базовый тип. Таким образом, компилятор не может выполнять работу, для которой предназначены дженерики.
Всякий раз, когда вы делаете такие объявления типа, не забудьте указать типы всех общих типов в объявлении и использовать переменные типа, которые правильно представляют отношения между ними.
Ответ 3
Я хотел добавить комментарий, но не мог, поскольку у меня недостаточно репутации.
ваши типы являются сырыми. ведущий в AbstractView является сырым типом, поскольку общие параметры, переданные в Abstract View, являются raw