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

2022-09-01 23:06:12

我有一个接受对象的方法。在一个用例中,该方法接受 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");
    }
}

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

我的问题是,我如何检查这里的类型转换?

HashMap<String, String> hashMap = (HashMap<String, String>) object;

提前致谢!

溶液

感谢@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();
    }
}

答案 1

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

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

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

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


答案 2

应该注意的是,原始例程完全等同于编码

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"));
    }
}

显式强制转换不可能引发错误,因为它由 .仅当从 HashMap 返回的值不是字符串(或 null)时,隐式提供的强制转换才会引发错误。(HashMap)instanceof(String)

(通过“完全等效”,我的意思是产生相同的字节码。