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.
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>.
The getSession method belongs to Struts2 so I can't modify it. I would like to avoid using @SuppressWarnings because other warnings can be useful.
I guess all Struts2 users in the world faced the same problem... is there an elegant solution?
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 other warning 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.
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 String
and Serializable
respectively, or
a generic method like the following that performs the typecast safely.
@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;
}
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With