如何解决这个Java类型的安全警告?

Nic*_*oul 12 java generics casting struts2

Map session = ActionContext.getContext().getSession();
session.put("user", user);
Run Code Online (Sandbox Code Playgroud)

此代码生成警告:类型安全:方法put(Object,Object)属于原始类型Map.应参数化对泛型类型Map <K,V>的引用.

Map<String, Serializable> session = (Map<String, Serializable>)ActionContext.getContext().getSession();
session.put("user", user);
Run Code Online (Sandbox Code Playgroud)

此代码生成警告:类型安全:未选中从Map转换为Map <String,Serializable>.

的getSession方法属于Struts2的,所以我不能修改它.我想避免使用@SuppressWarnings,因为其他警告可能很有用.

我想世界上所有Struts2用户都遇到了同样的问题......有一个优雅的解决方案吗?

And*_*anu 11

我认为除了@SuppressWarnings("未选中")之外还有其他任何方式.我相信你可以把它放在有问题的线上方,它只能压制那条线.

编辑:你也可以这样做,Map<?, ?> session = ActionContext.getContext().getSession();但我不确定你是多么愿意这样做; 你将无法以任何方式将任何东西放入地图中(因为编译器无法检查你所放置的类型),只能从中读取.


Ste*_*n C 5

解决此问题的最安全,最有效的方法可能是:

Map<?, ?> session = ActionContext.getContext().getSession();
Run Code Online (Sandbox Code Playgroud)

然后键入强制转换从会话映射中检索的对象。

@SuppressWarnings方法实际上将导致编译的代码相同。但是类型转换将是隐式的。即,通过查看源代码很难发现它。@SuppressWarnings注释可以(假设地)抑制表示实际错误的同一代码块中的其他警告。即,这将导致隐藏的类型转换之一,等等在运行时失败。

其他更昂贵的选择包括:

  • 从条目到条目的副本,从到分别将键和值分别投射到和Map<?, ?>的新Map<String, Serializable>实例,或StringSerializable

  • 如下所示的通用方法可以安全地执行类型转换。


@SuppressWarnings("unchecked")
public <K,V> Map<K,V> castMap(Map<?, ?> map, Class<K> kClass, Class<V> vClass) {
    for (Map.Entry<?, ?> entry : map.entrySet()) {
        kClass.cast(entry.getKey());
        vClass.cast(entry.getValue());
    }
    return (Map<K,V>) map;
}
Run Code Online (Sandbox Code Playgroud)