我认为这是两个不同的问题:
1. 如何创建一个与传入参数相同类型的新集合。
2. 如何在函数声明中表达调用者保证得到与传入相同类型的集合。
更简单的问题是2:
不可能。由于通用类型本身不能有通用类型参数,因此这是行不通的。您可以将其放入文档中,但函数声明必须如下所示:
public Collection<File> strings_to_files(Collection<String> strings) {}
调用者将需要将结果强制转换回传递的类型:
ArrayList<File> files = (ArrayList<File>)strings_to_files(new ArrayList<String>())
问题 1:
Tamas Rev 的一个回答提供了一种可能性。
然而,如果您不想使用反射(reflection),您可以创建自己的集合(collections),提供方法在每个集合对象本身上重新创建相同类型或副本的集合。这实际上非常简单:
public interface Collection<E> extends java.util.Collection<E> {
public Collection<E> copy();
public <F> Collection<F> newInstance();
}
public interface List<E> extends java.util.List<E>, Collection<E> {
@Override
public List<E> copy();
@Override
public <F> List<F> newInstance();
}
public class LinkedList<E> extends java.util.LinkedList<E> implements List<E> {
@Override
public LinkedList<E> copy() {
return new LinkedList<E>(this);
}
@Override
public <F> LinkedList<F> newInstance() {
return new LinkedList<F>();
}
}
你需要对每个需要的集合类都这样做。现在你可以在你的函数中使用这些集合:
public Collection<File> strings_to_files(Collection<String> strings)
{
Collection<File> files = strings.<File>newInstance();
for(String string : strings)
{
files.add(new File(string));
}
return files;
}
你仍然可以将你的集合传递给其他库。另一个优点是,你可以将其他有用的东西放入你的集合中,比如泛型参数的实际类对象,这样你就可以始终强制执行和检索泛型参数类型。
唯一的问题是,默认集合需要转换为你的集合才能使用。
C
是不可修改的集合类型,它也不会很好地工作。 - Ted Hopp