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

出了什么问题?


当前回答

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

在这里:

地图<字符串,字符串> 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;

其他回答

另一种解决方案是,如果您发现自己经常强制转换同一个对象,而又不想让@ suppresswarnings(“unchecked”)乱写代码,那么可以使用注释创建一个方法。通过这种方式,您可以集中转换,并希望减少出错的可能性。

@SuppressWarnings("unchecked")
public static List<String> getFooStrings(Map<String, List<String>> ctx) {
    return (List<String>) ctx.get("foos");
}

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

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

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

在这里:

地图<字符串,字符串> 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;

警告就是这样。一个警告。有时警告无关紧要,有时则不然。它们用来提醒你注意编译器认为可能是问题,但可能不是问题的东西。

在类型转换的情况下,它总是会给出一个警告。如果你绝对确定一个特定的强制转换是安全的,那么你应该考虑在行之前添加一个这样的注释(我不确定语法):

@SuppressWarnings (value="unchecked")

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

比如,如果你想用

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

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

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

那么当你使用

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

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