提问者:小点点

如何将对象转换为Map<String, Object>,避免未选中的转换和instanceof的非法泛型类型


我把我的JSON整齐地放进地图里

如果我这样做

if (rows instanceof List) {
    List<Map<String, Object>> rows = (List<Map<String, Object>>) rows);
}

我得到一个“未经检查的演员阵容”。如果我这样做了:

if (rows instanceof List<Map<String, Object>>) {
    List<Map<String, Object>> rows = List<Map<String, Object>>) rows);
}

我得到“instanceof的非法泛型类型”。

那么,在检查我是否可以转换时,正确的转换方法是什么?我到处都找遍了,但我找不到一个好的答案,然而这似乎是一个非常明显的用例,不应该是不可能的。


共2个答案

匿名用户

泛型类型信息在运行时不可用。这就是为什么您不能将参数化类型与instanceof一起使用。

解决此限制的一种方法是检查列表的元素是否确实是Map的实例

if (rows instanceof List) {
    List<?> rowsList = (List<?>) rows;
    boolean canCast = true;
    
    for (Object row : rowsList) {
        if (!(row instanceof Map)) {
            canCast = false;
            break;
        }
        
        Map<?, ?> rowMap = (Map<?, ?>) row;
        for (Map.Entry<?, ?> entry : rowMap.entrySet()) {
            if (!(entry.getKey() instanceof String) || !(entry.getValue() instanceof Object)) {
                canCast = false;
                break;
            }
        }
    }
    
    if (canCast) {
        List<Map<String, Object>> typedRows = (List<Map<String, Object>>) rows;
        // Do something with typedRows
    }
}

匿名用户

您的第一种方法的问题是强制转换未经检查,这意味着编译器不能保证强制转换在运行时成功。这可能会导致在运行时出现ClassCastException,这可能难以调试。

您的第二种方法的问题是您不能在instanceof检查中使用泛型类型。instanceof运算符仅适用于非参数化类型,例如List或Map。

将行变量安全地转换为List

if (rows instanceof List) {
    List << ? > list = (List << ? > ) rows;
    if (!list.isEmpty() && list.get(0) instanceof Map) {
        List < Map < String, Object >> rows = (List < Map < String, Object >> ) list;
        // rows is now a List<Map<String, Object>> that you can use
    }
}

在这里,我们首先检查行是否是List的实例。如果是,我们将其转换为List

通过这样做,您可以避免未经检查的强制转换,并确保强制转换在运行时成功。