如果对象实例为HashMap,如何检查键和值的类型?

Sha*_*vil 14 java object unchecked-cast

我有一个接受Object的方法.在一个用例中,该方法接受a HashMap<String, String>并将每个值设置为相应键名的属性.

public void addHelper(Object object) {
    if (object instanceof HashMap) {
        HashMap<String, String> hashMap = (HashMap<String, String>) object;
        this.foo = hashMap.get("foo");
        this.bar = hashMap.get("bar");
    }
}
Run Code Online (Sandbox Code Playgroud)

此类遵循特定接口,因此不能为这些属性添加setter.

我的问题是,如何检查此处的类型?

HashMap<String, String> hashMap = (HashMap<String, String>) object;
Run Code Online (Sandbox Code Playgroud)

提前致谢!

感谢@drobert的回答,这是我的更新代码:

public void addHelper(Object object) {
    if (object instanceof Map) {
        Map map = (Map) object;
        if (map.containsKey("foo")) this.foo = map.get("foo").toString();
        if (map.containsKey("bar")) this.bar = map.get("bar").toString();
    }
}
Run Code Online (Sandbox Code Playgroud)

dro*_*ert 20

你不能.由于类型擦除,反射将显示您有一个HashMap实例,但类型在运行时被删除.实际上,你有HashMap <Object,Object>.

也就是说,你仍然有一些选择,我建议你采取一些建议.其中:

  • 检查它是否是"Map"的实例而不是"HashMap".它将使您的API更加灵活,因为您很可能只关心您通过密钥而不是任何特定的强制进行快速访问
  • 利用java.util.Map的api定义'containsKey(Object)'和'get(Object)',这样你仍然可以安全地使用mapInst.get("stringKey"),即使不必进行强制转换.
  • 您不能确保所有值都是字符串,但您可以利用java.lang.Object的toString()方法,并为每个值获取String.

简而言之:像对待任何Map一样处理它,并尝试即使没有强制转换也以字符串形式访问键,并尝试通过执行空检查然后调用.toString()来将每个值用作String,并且您将更安全实现.


Hot*_*cks 7

需要注意的是,原来的例程完全等同于编码

public void addHelper(Object object) {
    if (object instanceof HashMap) {
        HashMap hashMap = (HashMap) object;
        this.foo = (String)(hashMap.get("foo"));
        this.bar = (String)(hashMap.get("bar"));
    }
}
Run Code Online (Sandbox Code Playgroud)

显式转换(HashMap)不可能抛出错误,因为它由instanceof. (String)如果从 HashMap 返回的值不是字符串(或空值),则隐式提供的强制转换只会引发错误。

(“完全等同于”是指产生相同的字节码。)