在 Java 中,如何转换 List<?>
至 List<T>
使用通用方法,以便我可以用单个方法调用替换如下模式:
List untypedList = new ArrayList(); // or returned from a legacy method
List<Integer> typedList = new ArrayList<Integer>();
for (Object item: untypedList)
typedList.add((Integer)item);
请注意,上述代码不会生成任何类型安全警告,理想情况下,您的解决方案也不应生成任何此类警告。
如果列出 Class<L>
,以下解决方案是否有效?有公共(public)默认构造函数吗?
public class ListUtil {
public static <T, L extends List<T>> L typedList(List<?> untypedList, Class<T> itemClass, Class<L> listClass) {
L list = null;
try {
list = listClass.newInstance();
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
}
for (Object item: untypedList)
list.add(itemClass.cast(item));
return list;
}
}
(请注意,如果 listClass.newInstance()
的实例没有公共(public)默认构造函数,则 InstantiationException
会抛出 IllegalAccessException
或 Class<L>
。如果该方法没有正确处理这些异常,可能会出现什么问题?)
注意事项:
-
T
是结果列表中每个项目的类型。 -
L
是我希望创建的列表类型(扩展了List<T>
)。 -
untypedList
是“无类型”输入列表,实际上与List<Object>
相同. -
itemClass
表示T
的运行时类. -
listClass
表示L
的运行时类.
最佳答案
我会使用 Guava及其 Iterables.filter(Iterable,Class)方法以及来自 Lists
类的工厂方法,如下所示:
List<?> original = ...;
List<String> typed = Lists.newArrayList(
Iterables.filter(original, String.class));
这实际上会检查原始列表中的每个对象,结果列表将仅包含那些属于给定类型(在本例中为 String
)或其子类型的实例的元素。我真的不认为让用户为生成的 List
类型提供 Class
并尝试通过反射实例化它是没有意义的。
关于java - 如何使用泛型在 Java 中将 List<?> 转换为 List<T>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3548733/