EDIT: Да, это может быть дубликат. Но в то время как другой вопрос сродни: «Что такое бензопила и как ее использовать?» моя больше похожа на «Я пытаюсь просверлить отверстие этой машиной здесь, и это не сработает - что случилось?». Конечно, ответ: «Не используйте бензопилу!» и легко найти, как только вы знаете, что имеете дело с бензопилой.Java Generics: параметры типа «вложенные»?
Но я даже не знал, что мой вопрос был связан с «сырыми типами против диких карт» и поэтому не нашел этого вопроса - так что, возможно, этот вопрос по-прежнему полезен для других, подобных мне.
ORIGINAL ВОПРОС: Скажем, у меня есть следующая структура данных, которая представляет собой элемент в моем пользовательском интерфейсе:
public static abstract class RowItem<T> {
public final T value;
public RowItem(T value) {
this.value = value;
}
}
Теперь, я хотел бы сделать следующее:
public static abstract class EpgRowItem<T> extends RowItem<Pair<String, T>> {
public EpgRowItem(Pair<String, T> value) {
super(value);
}
}
public static final class EpgRowProgramItem extends EpgRowItem<Program> {
public EpgRowProgramItem(Pair<String, Program> value) {
super(value);
}
}
public static final class EpgRowOtherDateItem extends EpgRowItem<LocalDate> {
public EpgRowOtherDateItem(Pair<String, LocalDate> value) {
super(value);
}
}
Итак, на словах: EpgRowItem
- это RowItem
, который содержит Pair
, первым элементом которого всегда является String
, а второй элемент может быть любым. Кроме того, EpgRowProgramItem
является EpgRowItem
, в котором вторым элементом пары является Program
. Аналогично, EpgRowOtherDateItem
представляет собой EpgRowItem
, в котором вторым элементом пары является LocalDate
.
Это похоже на работу, пока у меня это в другом месте в моем коде:
List<OverlayPresenter.EpgRowItem> programs = ...;
OverlayPresenter.EpgRowItem epgRowItem = programs.get(0);
String channelId = epgRowItem.value.first; // DOESN'T COMPILE?!
Я чувствую, что компилятор должен знать, что epgRowItem.value
должен всегда быть Pair<String, ?>
, и, следовательно, epgRowItem.value.first
должны ВСЕГДА быть String
.
На самом деле, это даже не похоже на первую часть, т.е. е. следующее не компилируется либо:
Pair<String, ?> pair = epgRowItem.value; // epgRowItem.value is an Object?!
Что я делаю неправильно? Я просто спрашиваю слишком много о дженериках Java?
Да, теперь я знаю ответ, это я конечно, дубликат. Но так как я спросил «наоборот» - начиная с конкретной проблемы, а не с ключевого слова высокого уровня, я думаю, что это все еще правильный вопрос и может быть полезен для других. –