我正在升级以下代码:
return this.getMethod().execute(mp);
执行方法有签名的地方:
public Map<String,Object> execute(Object mp)
我的代码期望该方法的返回为Map<String, List<Map<String, String>>>
,但编译器在转换时窒息。那么我可以/我如何让它正确投射?Java 5 和 6 之间是否有任何变化会使这成为编译时问题?
只要您确定返回的地图将只包含 type 的值List<Map<String, String>>
,那么您需要使用双重转换:
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;
通常对于此类问题,我发现以下构造很有用:
public final class Reinterpret {
@SuppressWarnings("unchecked")
public static <T> T cast(Object object) {
return (T)object;
}
}
您可以使用它,例如,像这样:
...
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));
...
正如您所猜想的那样,Java 泛型类型系统的这种非常精确的弱化受到 C++ 的 reinterpret_cast 运算符的启发,并且适用于类似的上下文;但是,它也可以用于其他一些情况,例如当您想减少演员表的冗长时,例如,
Map<String, Object> objectMap = Reinterpret.cast(stringMap);
Java 6 的类型推断足够强大(或足够弱,取决于您的观点),可以将右侧表达式转换为左侧所需的表达式;但是请注意,这适用于赋值,但不适用于函数调用,这就是为什么上面的示例需要在调用本身中完全指定参数类型的原因。