Нельзя применить адаптер, обобщенный как <Object, Object>
к Task<?, ?>
, потому что, кто знает, что такое подстановочные знаки? Это может быть Task<String, Integer>
, в этом случае границы адаптера не будут совпадать, и поэтому он не будет применим.
(Ну, может быть, в этом случае они в порядке, потому что они потребители, но компилятор не может сделать это самостоятельно. Если это , то Task.addTaskListener
нужно быть объявленным для получения TaskListener<? super T, ? super V>
для удовлетворения компилятора.)
Из-за способа объявления addTaskListener
вам необходимо передать слушателю с точно такими же общими границами. И это невозможно, когда вы объявляете их подстановочными знаками, поскольку у вас нет возможности вернуться к ним позже. Вместо этого вам нужно сделать метод родовым, что аналогично использованию подстановочных знаков ?
, за исключением того, что вы присваиваете им имена, чтобы вы могли ссылаться на них позже в методе:
public <T, V> void executeTask(Task<T, V> task, boolean handleException) {
task.addTaskListener(new TaskListener.Adapter<T, V>() {
@Override
public void failed(TaskEvent event) { /* ... */ }
});
getContext().getTaskService().execute(task);
}
Что касается второй части, я понятия не имею, мне она тоже выглядит хорошо. Возможно, это какая-то вводящая в заблуждение ошибка, исходящая от необработанных типов, хотя это кажется маловероятным, поскольку ни один универсальный параметр вообще не участвует в объявлении. Если компилятору по-прежнему не нравится переопределение после вышеуказанных изменений, возможно, проблема в другом месте (например, вы случайно поместили метод в область неправильного класса и т. Д.)