乐谱包含 Item 对象。所有项目都有一个位置和相关数据。数据可以是任何东西,笔记、歌词等。
interface Item<T>
{
Position getPosition();
T getData();
...
}
class NoteItem implements Item<Note>
{
Note getData() { .... }
...
}
class LyricsItem implements Item<Lyrics>
{
Lyrics getData { ... }
...
}
Score 类有一个获取特定类 Items 的方法:
public <T extends Item<E>, E> List<T> getItems(Class<T> itemClass)
{
//
}
如下所示,如果参数是 Item 的子类,
getItems()
有效。但如果它是 Item.class,返回值是一个对象列表,我期望一个 Items 列表......
NoteItem item = getItems(NoteItem.class).get(0); // Compiles OK
Item<?> item2= getItems(Item.class).get(0); // Compiles KO, return value is Object, not Item<Object> as I expected
我可以通过将结果显式转换为 (Item) 来修复第二行,但是有没有更好的方法来避免转换?
避免铸造的一个解决方案是将
getItems()
方法更改为:
<T> List<T> getItems(Class<T> aClass)
但是该方法的用户没有办法(除了 doc)知道该方法只接受 Item 类。处理这个问题的最佳方法是什么?
不确定这是最好的解决方案,但我最终使用了以下 getItems() 方法:
<T extends Item<?>> T getItems(Class<T> itemClass);
使两条线起作用:
NoteItem item = getItems(NoteItem.class).get(0); // Compiles OK
Item<?> item2= getItems(Item.class).get(0); // Compiles OK
唯一的小缺点是我在使用
getItems(Item.class)
时收到 rawtypes 警告,因为返回值是 List<Item>
,而不是 List<Item<?>>
.