У меня ошибка компилятора «несовместимых типов» в состоянии, которое еще не обсуждалось в stackoverflow (например, Why won't this generic java code compile?).Java generics & несовместимые типы: ошибка в компиляторе?
Мое ожидание простое - я вызываю шаблонный метод, который не использует какие-либо «общие» классы из класса, поэтому он должен извлекать типы параметров шаблона из аргументов метода, и это должно компилироваться во всех случаях - но я получить ошибку компилятора «несовместимые типы».
Я заметил странный способ исправить проблему - добавление «<? Extends Data>» в общий тип данных в аргументах метода. Как это изменяет логику компилятора?
В моем понимании - не должно быть никакой разницы, потому что параметры шаблона (1) DataContainer класса не используется в вызове метода и (2) ограничение „< TDATA расширяет данные>“ уже определяет минимальный базовый класс объекта - Data - и поэтому его следует автоматически принимать при компиляции шаблона без аргументов.
public void processData(DataContainer<? extends Data> c) {
(явное приведение типа может быть использован, но я считаю, что это избыточно здесь)
DummyContextClass dcc = (DummyContextClass)c.getContext(DummyContextClass.class);
код для копирования/вставки
public class Test {
public static class Data {
}
public static class DataContainer<TData extends Data> {
public final TData Data;
private final Map<String, Object> contexts = new HashMap<>();
public DataContainer(TData data) {
Data = data;
}
public <T> T getContext(Class<T> type) {
return (T)contexts.get(type.getName());
}
public <T> void setContext(Class<T> type, T context) {
contexts.put(type.getName(), context);
}
}
public static class DummyContextClass {
}
public void processData(DataContainer c) {
c.setContext(DummyContextClass.class, new DummyContextClass());
// error: incompatible types: Object cannot be converted to DummyContextClass
DummyContextClass dcc = c.getContext(DummyContextClass.class);
}
}
Вы можете удалить 'extends Data', поскольку он является избыточным. – Njol
Это кажется бессмысленным, поскольку кто-то может создать не-общий класс, который имеет общие методы, и это будет работать нормально. 'T' не имеет никакого отношения к' TData', поэтому нет никакой причины, чтобы эта общая информация была удалена. Это так же глупо, как переменные аргументы, обрабатывающие неквалифицированный «null» как нулевой массив вместо «new DataType [] {null}» только потому, что люди использовали явные массивы перед переменными аргументами. – JAB
@ user902383 Это не должно иметь никакого отношения к этому, параметр 'T' полностью не связан с' TData'. – JAB