23

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

此类遵循特定的接口,因此为这些属性添加设置器不是一种选择。

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

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();
    }
}
4

4 回答 4

26

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

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

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

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

于 2013-10-03T16:01:49.300 回答
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"));
    }
}

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

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

于 2013-10-03T18:05:09.353 回答
2

您应该在调用addHelper(Object)方法的地方使用 try-catch。这将确保您的HashMap.

      try{
        addHelper(hashMap);
        }
        catch(ClassCastException ex){
            System.out.println("Is not desired hashmap");
        }
于 2013-10-03T15:55:48.067 回答
0
   try{
    HashMap<String, String> hashMap = (HashMap<String, String>) object;
    this.foo = hashMap.get("foo");
    this.bar = hashMap.get("bar");
    }catch(ClassCastException e){
        System.err.log("Object is not a hashmap");
    }

现在,您知道该对象的类型是正确的——甚至是自定义抽象类或其他类型。

于 2013-10-03T15:48:16.743 回答