Type safety: Unchecked cast
Solution 1
Well, first of all, you're wasting memory with the new HashMap
creation call. Your second line completely disregards the reference to this created hashmap, making it then available to the garbage collector. So, don't do that, use:
private Map<String, String> someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
Secondly, the compiler is complaining that you cast the object to a HashMap
without checking if it is a HashMap
. But, even if you were to do:
if(getApplicationContext().getBean("someMap") instanceof HashMap) {
private Map<String, String> someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
}
You would probably still get this warning. The problem is, getBean
returns Object
, so it is unknown what the type is. Converting it to HashMap
directly would not cause the problem with the second case (and perhaps there would not be a warning in the first case, I'm not sure how pedantic the Java compiler is with warnings for Java 5). However, you are converting it to a HashMap<String, String>
.
HashMaps are really maps that take an object as a key and have an object as a value, HashMap<Object, Object>
if you will. Thus, there is no guarantee that when you get your bean that it can be represented as a HashMap<String, String>
because you could have HashMap<Date, Calendar>
because the non-generic representation that is returned can have any objects.
If the code compiles, and you can execute String value = map.get("thisString");
without any errors, don't worry about this warning. But if the map isn't completely of string keys to string values, you will get a ClassCastException
at runtime, because the generics cannot block this from happening in this case.
Solution 2
The problem is that a cast is a runtime check - but due to type erasure, at runtime there's actually no difference between a HashMap<String,String>
and HashMap<Foo,Bar>
for any other Foo
and Bar
.
Use @SuppressWarnings("unchecked")
and hold your nose. Oh, and campaign for reified generics in Java :)
Solution 3
As the messages above indicate, the List cannot be differentiated between a List<Object>
and a List<String>
or List<Integer>
.
I've solved this error message for a similar problem:
List<String> strList = (List<String>) someFunction();
String s = strList.get(0);
with the following:
List<?> strList = (List<?>) someFunction();
String s = (String) strList.get(0);
Explanation: The first type conversion verifies that the object is a List without caring about the types held within (since we cannot verify the internal types at the List level). The second conversion is now required because the compiler only knows the List contains some sort of objects. This verifies the type of each object in the List as it is accessed.
Solution 4
A warning is just that. A warning. Sometimes warnings are irrelevant, sometimes they're not. They're used to call your attention to something that the compiler thinks could be a problem, but may not be.
In the case of casts, it's always going to give a warning in this case. If you are absolutely certain that a particular cast will be safe, then you should consider adding an annotation like this (I'm not sure of the syntax) just before the line:
@SuppressWarnings (value="unchecked")
Solution 5
You are getting this message because getBean returns an Object reference and you are casting it to the correct type. Java 1.5 gives you a warning. That's the nature of using Java 1.5 or better with code that works like this. Spring has the typesafe version
someMap=getApplicationContext().getBean<HashMap<String, String>>("someMap");
on its todo list.
Related videos on Youtube
Sajal Dutta
Driven by boundless passion towards innovation and creative software engineering, I am a strategic leader with record of delivering large-scale systems and solutions, roll-outs, and efficient support operations across continents to enable sustainable business growth and market advantage for some of the top players in retail and financial businesses around the globe. My recipe for building high performing teams: product mindset, passionate engineers, and ownership by example. Personality Tests: https://www.crystalknows.com/p/sajaldutta Specialties: Problem Solving Systems Engineering Data Engineering (ML/AI) and Analytics Enterprise Systems implementation, roll-outs, and transition Large-scale project/program management People and large organization development Java (JEE), Spring, Python (3.x), SAP ERP (ECC, S/4HANA), FICO, SAP Business Intelligence (BI/BW), AWS, Azure, Ethereum and Solana Blockchains
Updated on July 27, 2021Comments
-
Sajal Dutta almost 3 years
In my spring application context file, I have something like:
<util:map id="someMap" map-class="java.util.HashMap" key-type="java.lang.String" value-type="java.lang.String"> <entry key="some_key" value="some value" /> <entry key="some_key_2" value="some value" /> </util:map>
In java class, the implementation looks like:
private Map<String, String> someMap = new HashMap<String, String>(); someMap = (HashMap<String, String>)getApplicationContext().getBean("someMap");
In Eclipse, I see a warning that says:
Type safety: Unchecked cast from Object to HashMap<String,String>
What went wrong?
-
Yaser Har over 15 yearsI came up with a routine to actually check the cast to parameterized HashMap, which eliminates the unchecked cast warning: link I'd say this is the "correct" solution, but whether or not its worth it might be debatable. :)
-
blahdiblah about 11 yearsRelated/dupe: How do I address unchecked cast warnings?
-
Angelo Fuchs over 9 yearspossible duplicate of How do I address unchecked cast warnings?
-
-
Dan Rosenstark almost 13 yearsI'll take Java's reified generics over untyped NSMutableWhatever, which feels like a ten-year leap backwards, any day of the week. At least Java is trying.
-
dubmojo about 12 yearsThis was a while ago, but I was looking for an answer on type checking a Set<CustomClass> before a cast, and you can't instanceof on a parametrized generic. e.g. if(event.getTarget instanceof Set<CustomClass>) You can only type check a generic with a ? and that won't remove the cast warning. e.g. if(event.getTarget instanceof Set<?>)
-
dubmojo about 12 yearsExactly. If you insist on type checking, it can only be done with HashMap<?,?> and that won't remove the warning since its the same as not type checking the generic types. It's not the end of the world, but annoying that you're caught either suppressing a warning or living with it.
-
ezdazuzena over 10 years-1: a warning should never be accepted. Or suppress these kind of warnings or fix it. There will come the moment where you'll have to many warnings and you won't see the relevant once.
-
muttonUp about 9 yearsYou can't really avoid class cast warnings when casting parameterised generics i.e Map, so this is the best answer for the original question.
-
juan Isaza over 8 yearsyou are right my friend. Instead of casting the list, just iterate it and cast each element, the warning will not appear, awesome.
-
SasQ about 8 years@JonSkeet What's a reified generic?
-
mumair over 7 yearsThis removed the warning but still I am not confident :P
-
channae over 5 yearsYes feels like blindfolding the compiler but not runtime :D So I don't see any difference between this and @SuppressWarnings("unchecked")
-
Edu Costa almost 5 yearsThat´s awesome! The main difference of using @SupressWarning is that it that use the annotation eliminates the warning from your IDE and code analysis tools but if you are using the -Werror flag compile you will end up with error yet. Using this approach both warnings are fixed.
-
Malwinder Singh over 4 yearsLooks like a hack not a solution.
-
Ulterior over 4 years- The serializable class MyMap does not declare a static final serialVersionUID field of type long :{
-
Line over 3 years@Ulterior then add such a field: stackoverflow.com/questions/2288937/…
-
Hiran Chaudhuri about 2 yearsIn baeldung.com/java-warning-unchecked-cast it is explained that a ClassCastException might be thrown anywhere in your code without reference to this offending unchecked cast. The workaround is to move the cast to something that has a very concise ClassCastException and thus can be fixed easier if need be.
-
Flimtix about 2 years@SasQ and all others who are wondering should take a look at this question.