类型安全:未选中的投射

2022-08-31 05:03:28

在我的弹簧应用程序上下文文件中,我有如下内容:

<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 中,我看到一条警告,上面写着:

类型安全:未选中从对象到哈希映射的强制转换<字符串,字符串>

哪里出错了?


答案 1

问题在于强制转换是运行时检查 - 但由于类型擦除,在运行时,a 和 与任何其他 和 之间实际上没有区别。HashMap<String,String>HashMap<Foo,Bar>FooBar

使用并捏住鼻子。哦,还有Java中重新化的泛型:)@SuppressWarnings("unchecked")


答案 2

好吧,首先,您正在通过新的创建调用来浪费内存。您的第二行完全忽略对此创建的哈希映射的引用,使其可供垃圾回收器使用。所以,不要这样做,使用:HashMap

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

其次,编译器抱怨您将对象转换为 ,而没有检查它是否为 .但是,即使您要这样做:HashMapHashMap

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

您可能仍然会收到此警告。问题是,返回 ,因此不知道类型是什么。直接将其转换为它不会引起第二种情况的问题(也许在第一种情况下不会有警告,我不确定Java编译器对Java 5的警告有多迂腐)。但是,您正在将其转换为 .getBeanObjectHashMapHashMap<String, String>

哈希映射实际上是将对象作为键并将对象作为值的映射,如果您愿意的话。因此,不能保证当您获得bean时,它可以表示为a,因为您可以拥有,因为返回的非泛型表示可以具有任何对象。HashMap<Object, Object>HashMap<String, String>HashMap<Date, Calendar>

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


推荐