我们假设,有一种方法可以返回Object
,但我们知道它是某种类型的List
(例如LinkedList<Long>
或ArrayList<String>
):
public abstract Object open();
直接使用其返回值
List<Long> result = (List<Long>)dialog.open();
会引发警告,例如:
类型安全:未选中从对象转换为列表
要解决此问题,我们可以转换为List<?>
,然后分别检查每个列表项:
List<?> result = (List<?>)dialog.open();
List<Long> safeResult = new LinkedList<Long>();
for (Object obj: result) {
if (obj instanceof Long) {
safeResult.add((Long)obj);
}
}
现在我想,拥有一个可以将Object
(已知包含List
)的通用方法强加给任何类型的{{1}实例并不是一件好事。 }}
这是我能得到的最接近的:
List
现在我可以像这样使用它:
private <T> List<T> doSafeCast(Object listObject, Class<T> type) {
List<T> result = new LinkedList<T>();
if (listObject instanceof List) {
List<?> list = (List<?>)listObject;
for (Object obj: list) {
if (type.isInstance(obj)) {
result.add(type.cast(obj));
}
}
}
return result;
}
但是,现在我必须只有List<Long> safeResult = this.doSafeCast(dialog.open(), Long.class);
s。
是否可以通过传递其他参数来指定列表类型?
我想要这样的事情:
LinkedList
我知道所有这些看起来过于复杂,如果我确定对话框将始终返回所需类型,我可以将List<Long> safeResult = this.doSafeCast(dialog.open(), Long.class, ArrayList.class);
List<String> anotherSafeResult = this.doSafeCast(anotherDialog.open(), String.class, LinkedList.class);
添加到我最初的不安全演员阵容中。但是我想出了一个通用方法来做这种安全演员的想法,现在我想知道,如果这是可能的话。所以请不要提出其他解决方案,我只是想了解一下如何使用泛型。 :-)谢谢。
答案 0 :(得分:1)
是的,你可以。只需为方法引入另一个类型参数,然后将其上传到List
:
private <T, L extends List<T>> List<T> doSafeCast(Object listObject,
Class<T> type,
Class<L> listClass) {
List<T> result = listClass.newInstance();
if (listObject instanceof List) {
List<?> list = (List<?>) listObject;
for (Object obj : list) {
if (type.isInstance(obj)) {
result.add(type.cast(obj));
}
}
}
return result;
}
请注意,您必须处理几个可能的例外情况。