Reputation: 23497
I am upgrading the following code:
return this.getMethod().execute(mp);
Where the execute method has signature:
public Map<String,Object> execute(Object mp)
I have code that expects the return of the method to be Map<String, List<Map<String, String>>>
, but the compiler is choking on the conversion. So can I / how do I get this to cast properly? And is there any change between Java 5 and 6 that would make this now a compile time issue?
Upvotes: 2
Views: 3813
Reputation: 55213
As long as you're sure that the returned map will only contain values of type List<Map<String, String>>
, then you need to use a double cast:
Map<String, Object> map = this.getMethod().execute(mp);
@SuppressWarnings("unchecked") //thoroughly explain why it's okay here
Map<String, List<Map<String, String>>> mapWithNarrowedTypes =
(Map<String, List<Map<String, String>>>)(Map<?, ?>)map;
return mapWithNarrowedTypes;
Upvotes: 7
Reputation: 11
Often for this type of problem I find useful the following construct:
public final class Reinterpret {
@SuppressWarnings("unchecked")
public static <T> T cast(Object object) {
return (T)object;
}
}
Which you can use, e.g., like this:
...
public void process(Map<String, Object> data) {
// method can properly handle any Object value,
// including String
}
...
Map<String, String> stringData = ...
process(Reinterpret.<Map<String, Object>>cast(stringData));
...
As you can guess, that very precise weakening of Java generics type system was inspired by C++'s reinterpret_cast operator, and is applicable in similar contexts; however, it can also be used in a few others, such as when you want to reduce the verbosity of your casts, e.g.,
Map<String, Object> objectMap = Reinterpret.cast(stringMap);
Java 6's type inference is strong enough (or weak enough, depending on your perspective) to cast the right-hand-side expression to what the left-hand-side requires; notice, however, that this works fine for assignments, but NOT for function calls, which is why the example above requires fully specifying the parametric types in the call itself.
Upvotes: 1