在我的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>
在java类中,实现看起来像:
private Map<String, String> someMap = new HashMap<String, String>();
someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
在Eclipse中,我看到一个警告说:
类型安全:未检查从Object转换到HashMap<String,String>
出了什么问题?
下面的代码导致类型安全警告
myInput = (Map<String, Object>) myRequest.get();
解决方案
创建一个新的Map Object而不提及参数,因为列表中持有的对象类型没有得到验证。
步骤1:创建一个新的临时Map
地图< ?, ?> tempMap = (Map<??>) myRequest.get();
步骤2:实例化主Map
Map<String, Object> myInput=new HashMap<>(myInputObj.size());
步骤3:迭代临时Map并将值设置到主Map中
for(Map.Entry<?, ?> entry :myInputObj.entrySet()){
myInput.put((String)entry.getKey(),entry.getValue());
}
我做错了什么?如何解决这个问题?
在这里:
地图<字符串,字符串> someMap =(文件夹<字符串,字符串>)getApplicationContext(“someMap”);
你使用一个我们通常不希望使用的遗留方法,因为它返回Object:
Object getBean(String name) throws BeansException;
从bean工厂获取(单例)/创建(原型)bean的方法是:
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
使用它,如:
Map<String,String> someMap = app.getBean(Map.class,"someMap");
将编译,但仍然带有未检查的转换警告,因为所有Map对象不一定是Map<String, String>对象。
但是<T> T getBean(字符串名称,类<T> requiredType)抛出BeansException;在bean泛型类(如泛型集合)中是不够的,因为这需要指定多个类作为参数:集合类型及其泛型类型。
在这种情况下以及一般情况下,更好的方法是不直接使用BeanFactory方法,而是让框架注入bean。
bean声明:
@Configuration
public class MyConfiguration{
@Bean
public Map<String, String> someMap() {
Map<String, String> someMap = new HashMap();
someMap.put("some_key", "some value");
someMap.put("some_key_2", "some value");
return someMap;
}
}
注豆:
@Autowired
@Qualifier("someMap")
Map<String, String> someMap;
如果您真的想摆脱警告,可以做的一件事是创建一个从泛型类扩展而来的类。
比如,如果你想用
private Map<String, String> someMap = new HashMap<String, String>();
您可以像这样创建一个新类
public class StringMap extends HashMap<String, String>()
{
// Override constructors
}
那么当你使用
someMap = (StringMap) getApplicationContext().getBean("someMap");
编译器确实知道(不再是泛型)类型是什么,并且不会有警告。这可能并不总是完美的解决方案,有些人可能会认为这违背了泛型类的目的,但你仍然重用了泛型类中的所有相同代码,你只是在编译时声明了你想使用的类型。