Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I address unchecked cast warnings?

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. 
like image 643
skiphoppy Avatar asked Feb 03 '09 21:02

skiphoppy


People also ask

How do I get rid of unchecked cast warning?

If we can't eliminate the “unchecked cast” warning and we're sure that the code provoking the warning is typesafe, we can suppress the warning using the SuppressWarnings(“unchecked”) annotation. When we use the @SuppressWarning(“unchecked”) annotation, we should always put it on the smallest scope possible.

What does unchecked cast mean?

Unchecked cast means that you are (implicitly or explicitly) casting from a generic type to a nonqualified type or the other way around.

What is suppress warning unchecked?

@SuppressWarnings("unchecked") is used when Java generics just don't let you do what you want to, and thus, you need to explicitly specify to the compiler that whatever you are doing is legal and can be executed at the time of execution.


2 Answers

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:

@SuppressWarnings("unchecked") Map<String, String> myMap = (Map<String, String>) deserializeMap(); 

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 a ClassCastException). This is why the code generates a warning, because the compiler can't possibly know whether is safe.

like image 155
Michael Myers Avatar answered Oct 25 '22 12:10

Michael Myers


Unfortunately, there are no great options here. Remember, the goal of all of this is to preserve type safety. "Java Generics" offers a solution for dealing with non-genericized legacy libraries, and there is one in particular called the "empty loop technique" in section 8.2. Basically, make the unsafe cast, and suppress the warning. Then loop through the map like this:

@SuppressWarnings("unchecked") Map<String, Number> map = getMap(); for (String s : map.keySet()); for (Number n : map.values()); 

If an unexpected type is encountered, you will get a runtime ClassCastException, but at least it will happen close to the source of the problem.

like image 42
Julien Chastang Avatar answered Oct 25 '22 11:10

Julien Chastang