Кто-нибудь, объясните мне следующее поведение. Есть класс
public class ClassMap<T> extends LinkedHashMap<Class<? extends T>, T> {
@SuppressWarnings("unchecked")
public void put(T item) {
put((Class<? extends T>) item.getClass(), item);
}
}
есть два объекта этого класса
private ClassMap<ServerSchedule> serverTasks = new ClassMap<ServerSchedule>() {
{
put(...);
put(...);
put(...);
put(...);
}
};
private ClassMap<SensorIdSchedule> sensorTasks= new ClassMap<SensorIdSchedule>() {
{
put(...);
put(...);
put(...);
put(...);
}
};
Есть методы
public final Single<SyncCondition<ServerSchedule>> syncCondition() {
return // Something
}
в ServerSchedule
и
public final Single<SyncCondition<? extends SensorIdSchedule>> syncCondition(String sensorId) {
this.sensorId = sensorId;
return syncCondition();
}
public abstract Single<SyncCondition<? extends SensorIdSchedule>> syncCondition();
в SensorIdSchedule
Вопрос же в следующем. Почему на вызов
List<SyncCondition<? extends SensorIdSchedule>> sensorConditions =
ListUtil.map(sensorTasks.keySet(), sClass -> sensorTasks.get(sClass).syncCondition(sensorId).blockingGet());
Компилятор не ругается, а на вызов
List<SyncCondition<? extends ServerSchedule>> serverConditions =
ListUtil.map(serverTasks.keySet(), sClass -> serverTasks.get(sClass).syncCondition().blockingGet());
ругается ещё как. Говорит что не List<SyncCondition<? extends ServerSchedule>> должен получаться, а List<Object>. Но для двух аследников Schedule всё сделано одинаково, в чем же разница?
PS Если это не очень понятно, то ListUtil.map() простой метод, который использует магию стримов, но скрывает ее реализацию:
public static <T, E> List<E> map(Collection<T> list, Function<? super T, ? extends E> function) {
return StreamSupport.stream(list)
.map(function)
.collect(Collectors.toList());
}
UPDATED
Похоже дело в том, что ServerSchedule параметризован, добавил непараметризованную прослойку между Schedule и SensorSchedule (какой является и SensorIdSchedule) и компиятор перестал ругаться
public abstract class JustSchedule extends Schedule {
public JustSchedule(Context context, HealbeClient healbeClient, long delay) {
super(context, healbeClient, delay);
}
public abstract Single<SyncCondition<? extends JustSchedule>> syncCondition();
}
Как развивать веб-проекты в 2026 году: технологии, контент E-E-A-T и факторы доверия
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники