当前位置:  开发笔记 > 编程语言 > 正文

类型安全:未经检查的演员

如何解决《类型安全:未经检查的演员》经验,为你挑选了6个好方法。

在我的spring应用程序上下文文件中,我有类似的东西:


    
       

在java类中,实现如下:

private Map someMap = new HashMap();
someMap = (HashMap)getApplicationContext().getBean("someMap");

在Eclipse中,我看到一条警告说:

类型安全:从Object到HashMap的未选中转换

我做错了什么?我该如何解决这个问题?



1> Jon Skeet..:

问题是转换是运行时检查 - 但是由于类型擦除,在运行时实际上a HashMapHashMap任何其他Foo和之间没有区别Bar.

使用@SuppressWarnings("unchecked")并抓住你的鼻子.哦,Java中的具体化泛型运动:)


我将把Java的具体化泛型与无类型的NSMutableWhatever相提并论,这就像是一周中任何一天的倒退十年.至少Java正在尝试.
究竟.如果你坚持进行类型检查,它只能用HashMap <?,?>来完成,并且不会删除警告,因为它与不检查泛型类型的类型相同.这不是世界的尽头,但令人烦恼的是你被抓住要么压制警告要么与它一起生活.
@JonSkeet什么是具体的通用?

2> MetroidFan20..:

好吧,首先,你正在用新的HashMap创作电话浪费记忆力.您的第二行完全忽略了对此创建的hashmap的引用,使其可用于垃圾收集器.所以,不要这样做,使用:

private Map someMap = (HashMap)getApplicationContext().getBean("someMap");

其次,编译器抱怨你将对象转换为a HashMap而不检查它是否是a HashMap.但是,即使你这样做:

if(getApplicationContext().getBean("someMap") instanceof HashMap) {
    private Map someMap = (HashMap)getApplicationContext().getBean("someMap");
}

您可能仍会收到此警告.问题是,getBean返回Object,所以不知道类型是什么.将其转换为HashMap直接不会导致第二种情况出现问题(并且在第一种情况下可能没有警告,我不确定Java编译器对Java 5的警告有多迂腐).但是,您正在将其转换为HashMap.

HashMaps实际上是将对象作为键并将对象作为值的映射,HashMap如果愿意的话.因此,无法保证当您获取bean时它可以表示为a,HashMap因为您可以拥有它,HashMap因为返回的非泛型表示可以包含任何对象.

如果代码编译,并且您可以执行String value = map.get("thisString");而没有任何错误,请不要担心此警告.但是如果映射不完全是字符串键的字符串键,那么你将ClassCastException在运行时得到一个,因为泛型不能阻止这种情况发生.


这是前一段时间,但我在寻找一个类型检查一个Set 之前的答案,并且你不能在参数化泛型上实例化.例如if(event.getTarget instanceof Set )你只能用一个?键入check a generic?并且不会删除演员警告.例如if(event.getTarget instanceof Set <?>)

3> 小智..:

如上面的消息所示,列表无法区分a List和a ListList.

我已经解决了类似问题的错误消息:

List strList = (List) someFunction();
String s = strList.get(0);

以下内容:

List strList = (List) someFunction();
String s = (String) strList.get(0);

说明:第一个类型转换验证对象是否为List,而不关心其中的类型(因为我们无法在List级别验证内部类型).现在需要进行第二次转换,因为编译器只知道List包含某种对象.这将在访问列表时验证列表中每个对象的类型.


你是对的我的朋友。除了强制转换列表并强制转换每个元素外,警告不会出现,这太棒了。

4> David M. Kar..:

警告就是这样.一个警告.有时警告是无关紧要的,有时它们不是.它们习惯于引起你注意编译器认为可能存在问题的东西,但可能不是.

在演员阵容的情况下,在这种情况下总是会发出警告.如果您完全确定特定的强制转换是安全的,那么您应该考虑在行之前添加这样的注释(我不确定语法):

@SuppressWarnings (value="unchecked")


-1:永远不应接受警告.或者压制这些警告或修复它.在你需要许多警告的那一刻,你将不会看到相关的一次.
在构建参数化泛型(即Map)时,您无法真正避免类强制转换警告,因此这是原始问题的最佳答案.

5> David Nehme..:

您收到此消息是因为getBean返回一个Object引用,并且您将其转换为正确的类型.Java 1.5会给出警告.这就是使用Java 1.5或更高版本的代码的性质.Spring有类型安全版本

someMap=getApplicationContext().getBean>("someMap");

在它的待办事项清单上.



6> Rabbit..:

如果你真的想摆脱警告,你可以做的一件事是创建一个从泛型类扩展的类.

例如,如果您正在尝试使用

private Map someMap = new HashMap();

您可以创建这样的新类

public class StringMap extends HashMap()
{
    // Override constructors
}

然后当你使用

someMap = (StringMap) getApplicationContext().getBean("someMap");

编译器知道(不再是通用)类型是什么,并且不会有警告.这可能并不总是完美的解决方案,有些人可能会认为这种方法违背了泛型类的目的,但你仍然在重复使用泛型类中的所有相同代码,你只是在编译时声明什么类型你想用.

推荐阅读
mobiledu2402851173
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有