我正在转换旧的java代码以支持泛型,并遇到了这行代码,它试图将从会话中检索到的对象转换为TreeMap
:
TreeMap allTransactions = (TreeMap) pageContext.getSession()
.getAttribute("allTransactions");
当我尝试将其转换为特定类型时:
TreeMap<String, MyDataBean> allTransactions = (TreeMap<String, MyDataBean>)
pageContext.getSession().getAttribute("allTransactions");
它给了我一个warning
:
Type safety: Unchecked cast from Object to TreeMap<String,MyDataBean>
为了彻底摆脱警告,我写了一个方法将它投射到Map
:
public static <K,V> Map<K,V> castToMap(Class<? extends K> clazz1,
Class<? extends V> clazz2, Map<?,?> c) {
Map<K,V> map = new TreeMap<K,V>();
for (Map.Entry<?,?> entry : c.entrySet()) {
Object key = entry.getKey();
Object value = entry.getValue();
map.put(clazz1.cast(key), clazz2.cast(value));
}
return map;
}
Goodnews :这次我修改初始代码以调用此方法时没有收到任何错误:
Map<String, MyDataBean> allTransactions = MyUtilityClass.castToMap(String.class,
MyDataBean.class,
(Map<?,?>)pageContext.getSession().getAttribute("allTransactions"));
但是我仍然需要将 ^^^ here 强制转换为我的函数。
问题1:
为什么现在我仍在使用演员(Map<?,?>)
与我在(TreeMap<String,MyDataBean>)
之前尝试的内容时没有显示任何错误?
问题2: 由于其他开发人员尚未提交代码,因此我的应用程序现已破损,因此我无法运行应用程序并验证其正确性。任何人都可以通过观察来判断,如果这个演员表现得和以前一样吗?
答案 0 :(得分:2)
如果它是Map
,那么它隐式地是Map<?,?>
- 就像在任何地图中一样。它认为这是一个安全的演员,因为它是一张地图,它不会失败。在这一点上,它与将其投射到任何其他对象没有什么不同,他们认为这是安全的。
如果它是一个糟糕的演员(说它是一个List,而不是一个Map)那么它会在出现任何其他错误之前爆炸。但是因为这些类型在编译时丢失了,如果问题出现在泛型类型中,它将很乐意继续。所以Map<?,?>
被认为是安全的,因为如果这是问题,它会因为不是地图而爆炸。
至于你的第二个问题,它看起来很好,但没有更多的背景,很难说。话虽这么说,您应该能够使用源代码管理中的历史记录来获取早期版本进行比较。如果您无法获得代码的早期版本,那么源代码控制不是很有用,现在是吗?
答案 1 :(得分:1)
Ad 1。:转换本身是安全的,因为您没有指定编译器无法与方法签名匹配的任何类型。 Java 4 List
可以安全地分配给Java 5 List<?>
,但是当您指定类型时,您会假设某些内容,编译无法安全地检查(因此警告)。
广告2:您已经使用“软”方法调用替换了“硬”语言强制转换,如果这些类不能相互转换,它将同样失败 - 我更喜欢语言强制转换的简洁版本,因为一个人应该依赖一个人的API。