Eclipse is giving me a warning of the following form:
Type safety: Unchecked cast from Object to HashMap
This is from a call to an API that I have no control over which returns Object:
HashMap<String, String> getItems(javax.servlet.http.HttpSession session) {
HashMap<String, String> theHash = (HashMap<String, String>)session.getAttribute("attributeKey");
return theHash;
}
I'd like to avoid Eclipse warnings, if possible, since theoretically they indicate at least a potential code problem. I haven't found a good way to eliminate this one yet, though. I can extract the single line involved out to a method by itself and add @SuppressWarnings("unchecked")
to that method, thus limiting the impact of having a block of code where I ignore warnings. Any better options? I don't want to turn these warnings off in Eclipse.
Before I came to the code, it was simpler, but still provoked warnings:
HashMap getItems(javax.servlet.http.HttpSession session) {
HashMap theHash = (HashMap)session.getAttribute("attributeKey");
return theHash;
}
Problem was elsewhere when you tried to use the hash you'd get warnings:
HashMap items = getItems(session);
items.put("this", "that");
Type safety: The method put(Object, Object) belongs to the raw type HashMap. References to generic type HashMap<K,V> should be parameterized.
The obvious answer, of course, is not to do the unchecked cast.
If it's absolutely necessary, then at least try to limit the scope of the
@SuppressWarnings
annotation. According to its Javadocs, it can go on local variables; this way, it doesn't even affect the entire method.Example:
There is no way to determine whether the
Map
really should have the generic parameters<String, String>
. You must know beforehand what the parameters should be (or you'll find out when you get aClassCastException
). This is why the code generates a warning, because the compiler can't possibly know whether is safe.Unfortunately, there are no great options here. Remember, the goal of all of this is to preserve type safety. "Java Generics" offers a solutions for dealing with non-genericized legacy libraries, and there is one in particular called the "empty loop technique" in section section 8.2. Basically, make the unsafe cast, and suppress the warning. Then loop through the map like this:
If an unexpected type is an encountered, you will get a runtime ClassCastException, but at least it will happen close to the source of the problem.
In Android Studio if you want to disable inspection you can use:
You can create a utility class like the following, and use it to suppress the unchecked warning.
You can use it as follows:
Some more discussion about this is here: http://cleveralias.blogs.com/thought_spearmints/2006/01/suppresswarning.html
Here's one way I handle this when I override the
equals()
operation.This seems to work in Java 8 (even compiled with
-Xlint:unchecked
)Almost every problem in Computer Science can be solved by adding a level of indirection*, or something.
So introduce a non-generic object that is of a higher-level that a
Map
. With no context it isn't going to look very convincing, but anyway:*Except too many levels of indirection.