无法从Map <string,object>转换为Map <string,list <map <string,string>&gt;&gt; </string,list <map <string,string> </string,object>

时间:2012-11-14 15:57:51

标签: java generics casting

我正在升级以下代码:

return this.getMethod().execute(mp);

执行方法有签名的地方:

public Map<String,Object> execute(Object mp)

我的代码期望返回方法为Map<String, List<Map<String, String>>>,但编译器对转换造成了阻碍。我可以/如何正确地进行演员? Java 5和6之间是否存在任何变化,这会使现在成为编译时问题?

2 个答案:

答案 0 :(得分:5)

只要你确定返回的地图只包含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;

答案 1 :(得分:1)

通常对于这类问题,我发现以下结构很有用:

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的类型推断足够强大(或者足够弱,取决于您的观点)将右侧表达式转换为左侧所需的表达式;但请注意,这适用于赋值,但不适用于函数调用,这就是上述示例需要在调用本身中完全指定参数类型的原因。