API设计题,带有泛型类的泛型方法

问题描述 投票:0回答:1

乐谱包含 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 类。处理这个问题的最佳方法是什么?

java generics api-design
1个回答
0
投票

不确定这是最好的解决方案,但我最终使用了以下 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<?>>
.

© www.soinside.com 2019 - 2024. All rights reserved.