比方说,我有一组来源,这些来源提供了一系列带标签的物品,其中物品的类型因来源而异。我想创建source方法的默认实现,但是在没有得到编译器有关未经检查的转换的警告的情况下,我一直无法找到一种方法。
首先,这是我的通用标签项目:
public class TaggedItem<T> {
private final String tag;
private final T item;
public TaggedItem(String tag, T item) {
this.tag = tag;
this.item = item;
}
public String getTag() { return tag; }
public T getItem() { return item; }
}
以及示例类型为String
的具体实现示例:
public class TaggedString extends TaggedItem<String> {
public TaggedString(String tag, String item) {
super(tag, item);
}
}
现在这是我的通用源界面:
public interface ITaggedItemSource<T> {
default TaggedItem<T>[] getTaggedItems() {
return new TaggedItem[0]; // (1)
}
default TaggedItem<T>[] getTaggedItems(Class<TaggedItem<T>> clazz) {
return (TaggedItem<T>[])Array.newInstance(clazz, 0); // (2)
}
default List<TaggedItem<T>> getTaggedItemList() {
return new ArrayList<TaggedItem<T>>();
}
}
我从第一种方法开始。但是,这会在(1)
处引起以下编译器警告:
Type safety: The expression of type TaggedItem[] needs unchecked conversion to conform to TaggedItem<T>[]
所以我添加了第二种方法。但是,这会导致在(2)
Type safety: Unchecked cast from Object to TaggedItem<T>[]
最后,对于第三种方法,我将数组转换为List
,并且没有警告。
为了记录,这是一个具体来源的例子。
public class TaggedStringSource implements ITaggedItemSource<String> {
@Override
public TaggedItem<String>[] getTaggedItems() {
TaggedString[] items = new TaggedString[1];
items[0] = new TaggedString("t1", "data");
return items;
}
@Override
public TaggedItem<String>[] getTaggedItems(Class<TaggedItem<String>> clazz) {
TaggedString[] items = new TaggedString[1];
items[0] = new TaggedString("t1", "data");
return items;
}
@Override
public List<TaggedItem<String>> getItemList() {
List<TaggedItem<String>> items = new ArrayList<>();
items.add(new TaggedString("t1", "data"));
return items;
}
我应该注意,尽管有编译器警告,但默认数组和List
实现都可以正常工作。 (正如您所料,我想毕竟它们只是警告。)
我的问题是:
Lists
时可以避免警告?