My Java application is displaying some odd behaviour, and I’m having trouble finding a solution.
This code snippet takes the contents of a LinkedHashMap where the keys and values are both of type String and writes them to a text file. configWriter is of type PrintWriter.
for (Map.Entry<String, String> entry : configMap.entireSet()) {
configWriter.println(entry.getKey() + "=" + entry.getValue());
}
The map was declared:
LinkedHashMap<String, String> configMap = new LinkedHashMap<String, String>();
It is populated by reading tokens from a text file using the Scanner class.
One of the values in the map is a String that contains only numbers (an integer), but when the loop gets to this value, it throws a ClassCastException saying that you cannot cast from Integer to String. This makes perfect sense, but the type of the values is String.
Is there a way to force Java to keep this value as a String?
It’s almost certain that rawtypes are getting used somewhere and there’s an
Integersneaking its way into the map.The easiest way to identify where an
Integeris getting inserted into the map is to replace the initialization ofconfigMapwithwhich will actually throw an exception if something other than a
Stringgets inserted into the map. I wouldn’t personally use that in production code, but this is probably the simplest way to “smoke out” the bug; you’ll get an exception and a stack trace for where exactly theIntegeris getting inserted.As it stands, the way generics are implemented with type erasure means that there’s nothing actually stopping non-
Stringvalues from being inserted into the map. The compiler makes some effort to prevent it, but rawtypes and legacy code can get around it. UsingCollections.checkedMapwill force the issue, though.