我在这里苦苦挣扎。
要开始,我想通过以下回调接口返回对象列表:
回调界面:
public interface ArrayCallback<T> {
public void onComplete(List<T> result);
}
到目前为止一切顺利。现在,使用该回调,假设我想得到如此的歌曲列表:
使用回调加载歌曲列表
public void loadSongs(ArrayCallback<Song> callback) {
List<Song> songs = new ArrayList<Song>();
...
callback.onComplete(songs);
}
这里没问题。但现在我想加载一些类型的音乐项目列表。它可能是以前的歌曲,但它可能是专辑,艺术家等。我称之为所有这些类型的事物的超类MusicItem
。 (因此,Song
有一个超级MusicItem
),这就是它所在的位置。
Aaaa以下内容不起作用
public void loadMusicItems(MusicItemType type, ArrayCallback<? extends MusicItem> callback) {
switch (type) {
case Songs:
loadSongs(callback);
break;
case Albums:
loadAlbums(callback);
break;
default:
break;
}
问题出在loadSongs(callback)
行。我无法调用此方法,因为类型不同。
loadSongs(ArrayCallback<Song>) in MusicSource cannot be applied to loadSongs(ArrayCallback<capture<? extends MusicItem>>)
根据我的理解,我不能只使用类型T
,因为协方差问题需要使用通配符。
我正在做什么甚至可能?在写完这个问题之后,我认为如果我突然限制方法调用的界限,编译器看起来会有些奇怪。除了可能是疯狂的方法设计之外,我仍然有兴趣弄清楚我做错了什么。
答案 0 :(得分:2)
通用类型仅在编译期间应用(以确保类型安全)并在运行期间消失。因此,您的实现实际上违反了泛型类型的使用。例如。您可以使用Album类型的ArrayCallback传递Song类型枚举。 (想象你的loadSongs方法将接收Album类型的ArrayCallback。没办法!)