Dra*_*orn 248 java spring unchecked type-safety
在我的spring应用程序上下文文件中,我有类似的东西:
<util:map id="someMap" map-class="java.util.HashMap" key-type="java.lang.String" value-type="java.lang.String">
<entry key="some_key" value="some value" />
<entry key="some_key_2" value="some value" />
</util:map>
Run Code Online (Sandbox Code Playgroud)
在java类中,实现如下:
private Map<String, String> someMap = new HashMap<String, String>();
someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
Run Code Online (Sandbox Code Playgroud)
在Eclipse中,我看到一条警告说:
类型安全:从Object到HashMap的未选中转换
我做错了什么?我该如何解决这个问题?
Jon*_*eet 303
问题是转换是运行时检查 - 但是由于类型擦除,在运行时实际上a HashMap<String,String>和HashMap<Foo,Bar>任何其他Foo和之间没有区别Bar.
使用@SuppressWarnings("unchecked")并抓住你的鼻子.哦,Java中的具体化泛型运动:)
Met*_*002 240
好吧,首先,你正在用新的HashMap创作电话浪费记忆力.您的第二行完全忽略了对此创建的hashmap的引用,使其可用于垃圾收集器.所以,不要这样做,使用:
private Map<String, String> someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
Run Code Online (Sandbox Code Playgroud)
其次,编译器抱怨你将对象转换为a HashMap而不检查它是否是a HashMap.但是,即使你这样做:
if(getApplicationContext().getBean("someMap") instanceof HashMap) {
private Map<String, String> someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
}
Run Code Online (Sandbox Code Playgroud)
您可能仍会收到此警告.问题是,getBean返回Object,所以不知道类型是什么.将其转换为HashMap直接不会导致第二种情况出现问题(并且在第一种情况下可能没有警告,我不确定Java编译器对Java 5的警告有多迂腐).但是,您正在将其转换为HashMap<String, String>.
HashMaps实际上是将对象作为键并将对象作为值的映射,HashMap<Object, Object>如果愿意的话.因此,无法保证当您获取bean时它可以表示为a,HashMap<String, String>因为您可以拥有它,HashMap<Date, Calendar>因为返回的非泛型表示可以包含任何对象.
如果代码编译,并且您可以执行String value = map.get("thisString");而没有任何错误,请不要担心此警告.但是如果映射不完全是字符串键的字符串键,那么你将ClassCastException在运行时得到一个,因为泛型不能阻止这种情况发生.
小智 79
如上面的消息所示,列表无法区分a List<Object>和a List<String>或List<Integer>.
我已经解决了类似问题的错误消息:
List<String> strList = (List<String>) someFunction();
String s = strList.get(0);
Run Code Online (Sandbox Code Playgroud)
以下内容:
List<?> strList = (List<?>) someFunction();
String s = (String) strList.get(0);
Run Code Online (Sandbox Code Playgroud)
说明:第一个类型转换验证对象是否为List,而不关心其中的类型(因为我们无法在List级别验证内部类型).现在需要进行第二次转换,因为编译器只知道List包含某种对象.这将在访问列表时验证列表中每个对象的类型.
Dav*_*arr 28
警告就是这样.一个警告.有时警告是无关紧要的,有时它们不是.它们习惯于引起你注意编译器认为可能存在问题的东西,但可能不是.
在演员阵容的情况下,在这种情况下总是会发出警告.如果您完全确定特定的强制转换是安全的,那么您应该考虑在行之前添加这样的注释(我不确定语法):
@SuppressWarnings (value="unchecked")
Run Code Online (Sandbox Code Playgroud)
您收到此消息是因为getBean返回一个Object引用,并且您将其转换为正确的类型.Java 1.5会给出警告.这就是使用Java 1.5或更高版本的代码的性质.Spring有类型安全版本
someMap=getApplicationContext().getBean<HashMap<String, String>>("someMap");
Run Code Online (Sandbox Code Playgroud)
在它的待办事项清单上.
避免未检查警告的解决方案:
class MyMap extends HashMap<String, String> {};
someMap = (MyMap)getApplicationContext().getBean("someMap");
Run Code Online (Sandbox Code Playgroud)
如果你真的想摆脱警告,你可以做的一件事是创建一个从泛型类扩展的类.
例如,如果您正在尝试使用
private Map<String, String> someMap = new HashMap<String, String>();
Run Code Online (Sandbox Code Playgroud)
您可以创建这样的新类
public class StringMap extends HashMap<String, String>()
{
// Override constructors
}
Run Code Online (Sandbox Code Playgroud)
然后当你使用
someMap = (StringMap) getApplicationContext().getBean("someMap");
Run Code Online (Sandbox Code Playgroud)
编译器知道(不再是通用)类型是什么,并且不会有警告.这可能并不总是完美的解决方案,有些人可能会认为这种方法违背了泛型类的目的,但你仍然在重复使用泛型类中的所有相同代码,你只是在编译时声明什么类型你想用.
| 归档时间: |
|
| 查看次数: |
335156 次 |
| 最近记录: |