编辑:是的,这可能是重复的。但另一个问题类似于"什么是电锯?如何使用它?"我更喜欢"我正试图在这里用这台机器钻一个洞而且它不起作用 - 它是什么?"。当然答案是"不要使用电锯!"一旦你知道你正在处理电锯,就很容易找到。
但我甚至不知道我的问题与"原始类型与外卡相关"因此没有找到这个问题 - 所以也许这个问题对像我这样的人来说仍然有用。
原始问题我们说我有以下数据结构代表我的用户界面中的项目:
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
。
实际上,它似乎甚至不知道第一部分,i。即以下不编译:
Pair<String, ?> pair = epgRowItem.value; // epgRowItem.value is an Object?!
我做错了什么?我只是过多地问过Java的泛型?
答案 0 :(得分:4)
您遇到了麻烦,因为您使用的是原始类型<div class="svg-counter">
<svg class="counter" x="0px" y="0px" viewBox="0 0 776 628">
<path class="track" d="M723 314L543 625.77 183 625.77 3 314 183 2.23 543 2.23 723 314z"></path>
<path class="fill" d="M723 314L543 625.77 183 625.77 3 314 183 2.23 543 2.23 723 314z"></path>
</svg>
</div>
(原始类型是一种参数化类型,您没有为其指定类型参数;这些是因为向后兼容Java 1.4及更早版本而存在): / p>
EpgRowItem
请参阅:What is a raw type and why shouldn't we use it?
使用类型参数,或至少使用通配符:
List<OverlayPresenter.EpgRowItem> programs = ...;
OverlayPresenter.EpgRowItem epgRowItem = programs.get(0);