如何解决此 Java 类型安全警告?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2927370/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 14:34:21  来源:igfitidea点击:

How to solve this Java type safety warning?

javagenericscastingstruts2

提问by Nicolas Raoul

Map session = ActionContext.getContext().getSession();
session.put("user", user);

This code generates a warning: Type safety: The method put(Object, Object) belongs to the raw type Map. References to generic type Map<K,V> should be parameterized.

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

Map<String, Serializable> session = (Map<String, Serializable>)ActionContext.getContext().getSession();
session.put("user", user);

This code generates a warning: Type safety: Unchecked cast from Map to Map<String,Serializable>.

此代码生成警告:类型安全:未检查从 Map 到 Map<String,Serializable> 的强制转换

The getSessionmethod belongs to Struts2 so I can't modify it. I would like to avoid using @SuppressWarnings because other warnings can be useful.

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

I guess all Struts2 users in the world faced the same problem... is there an elegant solution?

我猜世界上所有的 Struts2 用户都面临着同样的问题……有没有一个优雅的解决方案?

采纳答案by Andrei Fierbinteanu

I don't think there's any other way but @SuppressWarnings("unchecked"). I believe you can put it just above the line in question, and it will only suppress that line.

我认为除了@SuppressWarnings("unchecked") 之外别无他法。我相信你可以把它放在有问题的线上方,它只会抑制那条线。

Edit: you can also do Map<?, ?> session = ActionContext.getContext().getSession();but I'm not sure how willing you are to do that; you won't be able to put anything into the map that way (since the compiler can't check the type of what you're putting), only read from it.

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

回答by zed_0xff

What if you do it like this:

如果你这样做怎么办:

Map<String, Serializable> session = ActionContext.getContext().getSession();

回答by Tommi

What version of Struts 2 (especially XWork) are you using? For me, your following code gives an error:

XWork您使用的是什么版本的 Struts 2(尤其是)?对我来说,您的以下代码给出了错误:

Map<String, Serializable> session = (Map<String, Serializable>)ActionContext.getContext().getSession();
session.put("user", user);

Cannot cast from Map<String,Object> to Map<String,Serializable>.

This, on the other hand, works and gives no warnings:

另一方面,这有效并且没有警告:

Map<String, Object> session = ActionContext.getContext().getSession();

回答by Stephen C

The safest, most efficient way to deal with this is probably:

处理这个问题最安全、最有效的方法可能是:

Map<?, ?> session = ActionContext.getContext().getSession();

and then type cast the objects retrieved from the session map.

然后键入从会话映射中检索到的对象。

The @SuppressWarnings approach will actually result in compiled code that is identical. However the type cast will be implicit; i.e. it won't be easy to spot by looking at the source code. And the @SuppressWarnings annotation could (hypothetically) suppress some otherwarning in the same code block that represents a real error; i.e. one that will result in one of the hidden typecasts, etc failing at runtime.

@SuppressWarnings 方法实际上会导致编译后的代码完全相同。然而,类型转换将是隐式的;即通过查看源代码不容易发现。并且@SuppressWarnings 注释可以(假设)抑制同一代码块中代表真正错误的一些其他警告;即会导致隐藏类型转换之一等在运行时失败。

Other more expensive alternatives include:

其他更昂贵的替代品包括:

  • an entry by entry copy from the Map<?, ?>to a new Map<String, Serializable>instance casting the keys and values to Stringand Serializablerespectively, or

  • a generic method like the following that performs the typecast safely.

  • 一个条目从一个条目复制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;
}

回答by user3828314

It is requesting you to parameterize the value, if the value needs parameters then pass them.

它要求您参数化该值,如果该值需要参数则传递它们。

For example

例如

Map<Integer, Map> vCombinedCodeMap = new HashMap<>();

will give warning for "parameterized" Map<Integer, Map>.

将对 "parameterized" 发出警告Map<Integer, Map>

so the correct format is the following:

所以正确的格式如下:

Map<Integer, Map<String, String>> vCombinedCodeMap = new HashMap<>();

回答by Satish Shah

Cast as Following,

铸造如下,

public void setSession(Map<String, Object> sessionMap) {

    // TODO Auto-generated method stub

    this.sessionMap = (SessionMap<String, Object>) sessionMap;
}

回答by karthik

just write @SuppressWarnings("unchecked")at top of the @GETmethod, hope it will help you.

@SuppressWarnings("unchecked")@GET方法写在上面,希望对你有帮助。