2014-02-11 21 views
0

我将老的Java代码来支持泛型和跨越这行代码试图投从会话中检索对象到传来一个TreeMap如何将会话对象转换为Map?

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; 
} 

真证:这时候,我修改了最初的代码来调用这个方法我没有得到任何错误:

Map<String, MyDataBean> allTransactions = MyUtilityClass.castToMap(String.class, 
                   MyDataBean.class, 
      (Map<?,?>)pageContext.getSession().getAttribute("allTransactions")); 

但我仍然不得不投它^^^在这里来调用我的功能。

问题1: 为什么当我仍在使用中投(Map<?,?>)对我(TreeMap<String,MyDataBean>)尝试过它不显示任何错误呢?

问题2: 我的应用程序被打破截至目前因为其他开发商还没有犯下的代码还没有,所以我没有立场来运行应用程序,并验证其正确性。任何人都可以通过观察它来判断,如果这个铸件的行为与以前一样?

+0

我看不出添加该方法的意义。它没有实现任何具体。一个Map是一个Map,通用符号只是窗口修饰 - 可能在编写新代码时用作调试辅助工具,但当你知道代码的工作原理时,它就会阻碍你。 –

+0

请注意,'TreeMap'有一个构造函数,它需要一张地图。所以你的演员可以简单地返回新的TreeMap (c);'http://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html#TreeMap(java.util.Map) – corsiKa

+0

@HotLicks我不得不摆脱警告。你能否提出一个替代方案? – Prince

回答

2

如果它是一个Map那么它隐含地是一个Map<?,?> - 如在任何东西的地图。它认为这是一个安全的演员,因为它是一张地图,它不会失败。在这一点上,将它投射到任何其他物体上并没有什么不同,它们假定它是安全的。

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

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

+0

如果'it'是一个Map,那么它隐式地是一个Map - 你的意思是会话对象? – Prince

+0

不,我的意思是'pageContext.getSession()。getAttribute(“allTransactions”)'' - 这就是你最终投的东西,对吧? – corsiKa

+0

是的,那是我正在铸造的东西。但是,“TreeMap '有什么问题?我在这里的类型更清晰。 – Prince

1

广告1 .:投射本身是安全的,因为您没有指定编译器无法匹配方法签名的任何类型。 Java 4 List可以安全地分配给Java 5 List<?>,但是当你指定一个类型时,你认为是某种东西,编译不能安全地检查(因此警告)。

广告2:您用“软”方法调用强制类型替换了一个“硬”语言强制类型转换,如果这些类不能相互转换,那么这种调用将失败,我宁愿使用较不详细的语言强制转换,因为应该依靠一个人的API。

+0

我不明白你的意思是'硬'语言演员。你能否简单地解释你的'Ad2'解释? – Prince

+0

我认为他的意思是硬演员有定义的泛型类型,而软演员只是改变引用类型(当然不是基础类类型)。 – corsiKa

+1

'TreeMap allTransactions =(TreeMap )pageContext.getSession()。getAttribute(“allTransactions”);'是一种语言强制转换,因为您使用Java语言结构来转换getAttribute ()'而'clazz1.cast(key)'使用封装在方法调用中的cast。 – Smutje