在我的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>

出了什么问题?


当前回答

如上面的消息所示,List不能区分List<Object>和List<String>或List<Integer>。

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

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

与以下:

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

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

其他回答

下面的代码导致类型安全警告

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

避免未检查警告的解决方案:

class MyMap extends HashMap<String, String> {};
someMap = (MyMap)getApplicationContext().getBean("someMap");

您得到这条消息是因为getBean返回了一个Object引用,并且您正在将它强制转换为正确的类型。Java 1.5给出了一个警告。这就是使用Java 1.5或更高版本代码的本质。Spring有类型安全版本

someMap=getApplicationContext().getBean<HashMap<String, String>>("someMap");

在待办事项清单上。

如上面的消息所示,List不能区分List<Object>和List<String>或List<Integer>。

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

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

与以下:

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

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

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

比如,如果你想用

private Map<String, String> someMap = new HashMap<String, String>();

您可以像这样创建一个新类

public class StringMap extends HashMap<String, String>()
{
    // Override constructors
}

那么当你使用

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

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