如何将Session对象转换为Map?

时间:2014-02-11 21:37:57

标签: java session generics map casting

我正在转换旧的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: 由于其他开发人员尚未提交代码,因此我的应用程序现已破损,因此我无法运行应用程序并验证其正确性。任何人都可以通过观察来判断,如果这个演员表现得和以前一样吗?

2 个答案:

答案 0 :(得分:2)

如果它是Map,那么它隐式地是Map<?,?> - 就像在任何地图中一样。它认为这是一个安全的演员,因为它是一张地图,它不会失败。在这一点上,它与将其投射到任何其他对象没有什么不同,他们认为这是安全的。

如果它是一个糟糕的演员(说它是一个List,而不是一个Map)那么它会在出现任何其他错误之前爆炸。但是因为这些类型在编译时丢失了,如果问题出现在泛型类型中,它将很乐意继续。所以Map<?,?>被认为是安全的,因为如果这是问题,它会因为不是地图而爆炸。

至于你的第二个问题,它看起来很好,但没有更多的背景,很难说。话虽这么说,您应该能够使用源代码管理中的历史记录来获取早期版本进行比较。如果您无法获得代码的早期版本,那么源代码控制不是很有用,现在是吗?

答案 1 :(得分:1)

Ad 1。:转换本身是安全的,因为您没有指定编译器无法与方法签名匹配的任何类型。 Java 4 List可以安全地分配给Java 5 List<?>,但是当您指定类型时,您会假设某些内容,编译无法安全地检查(因此警告)。

广告2:您已经使用“软”方法调用替换了“硬”语言强制转换,如果这些类不能相互转换,它将同样失败 - 我更喜欢语言强制转换的简洁版本,因为一个人应该依赖一个人的API。