在java中运行时类型检查和转换

时间:2014-08-26 14:00:53

标签: java arraylist casting warnings typechecking

我有一个字符串和对象的地图,我从外部源获取此地图,对于特定情况,我将此对象作为

"ArrayList<LinkedHashMap<String, Double>>"

ArrayList<LinkedHashMap<String, Double>> targetDetailContainer = null;
Map<String, Object> confData = getConfData();
if (confData.containsKey("Target-Details")) {
    targetDetailContainer = (ArrayList<LinkedHashMap<String, Double>>) confData
            .get((Object) "Target-Details");
}

现在在我将对象转换为

的最后一行
"ArrayList<LinkedHashMap<String, Double>>"

我收到警告 -

类型安全:取消选中从对象转换为

"ArrayList<LinkedHashMap<String, Double>>"

我试图在转换之前进行类型检查,类似这样,

if (confData.containsKey("Target-Details")
    && confData.get((Object) "Target-Details") instanceof ArrayList<?>) {
targetDetailContainer = (ArrayList<LinkedHashMap<String, Double>>) confData
        .get((Object) "Target-Details");
}

但它没有奏效。请提出建议,如何摆脱这种警告。

5 个答案:

答案 0 :(得分:3)

我建议@SuppressedWarnings ("unchecked")注释,因为你不能对这个警告做很多事情。它不是很有害,但由于类型擦除和编译时缺少类型信息(对于泛型类型),你可以做其他任何事情。

答案 1 :(得分:2)

警告将作为编译类型检查的一部分存在,以防止将超类型的对象转换为特定类型的对象。这是编译器告诉您的方式。

&#34;嘿,我无法确定您投射的对象是ArrayList<LinkedHashMap<String, Double>>的对象,当您将此对象视为此类型时,请为RuntimeExceptions.So做好准备。现在,你是独立的。&#34;

如果你只想摆脱这个异常并且你已经准备好可能发生的任何RuntimeException,请继续并用 @SuppressedWarning ("unchecked") 标记它。但我建议你做一些防御机制并编辑你的代码

    ArrayList<LinkedHashMap<String, Double>> targetDetailContainer = null;
    Map<String, Object> confData = getConfData();

    if (confData.containsKey("Target-Details")) {

        Object value = confData.get("Target-Details");
        if (value instanceof ArrayList<?>) {
            ArrayList temp = (ArrayList) value;
            for (Object vals : temp) {
                boolean flag = false;
                if (vals instanceof LinkedHashMap<?, ?>) {
                    LinkedHashMap<?, ?> map = (LinkedHashMap) vals;
                    for (Map.Entry entry : map.entrySet()) {
                        if (entry.getKey() instanceof String
                                && entry.getValue() instanceof Double) {
                            flag = true;
                        }

                        if (!flag) {
                            throw new RuntimeException(
                                    "Objects are of different types");
                        }

                    }

                }
                targetDetailContainer = (ArrayList<LinkedHashMap<String, Double>>) confData
                        .get((Object) "Target-Details");
            }

        }
    }

由于检查很大并且编译器无法确定它,它会为您提供未经检查的警告

答案 2 :(得分:0)

您可以添加

@SuppressWarnings("unchecked")

在您的方法之前禁止此警告。

答案 3 :(得分:0)

confData.get((Object)&#34; Target-Details&#34; 的返回值存储在对象中,然后键入check that object以删除警告。

由于你曾两次调用 confData.get((Object)&#34; Target-Details&#34; ,因此它将它们视为两个不同的对象,一个是您键入的对象,一个是您没&#39;吨

应该是这样的:

Object temp = confData
    .get((Object) "Target-Details");


if (confData.containsKey("Target-Details")
&& temp instanceof ArrayList<?>) {
targetDetailContainer = (ArrayList<LinkedHashMap<String, Double>>) temp;
}

上面的代码可能有拼写错误,因为我通过移动应用程序键入,但概念是使用临时对象。

应避免使用抑制警告,因为这是不可取的,会对代码质量产生负面影响。

答案 4 :(得分:0)

由于编译时检查抱怨你从ObjectArrayList<LinkedHashMap<String, Double>>的投射,你几乎什么也做不了。只需将注释@SuppressWarnings("unchecked")放在方法之前。