Java 如果Object instanceof HashMap,如何检查键和值的类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19163453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 14:38:25  来源:igfitidea点击:

How to check types of key and value if Object instanceof HashMap?

javaobjectunchecked-cast

提问by Shaun Scovil

I have a method that accepts an Object. In one use case, the method accepts a HashMap<String, String>and sets each value to the property of the corresponding key name.

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

This class adheres to a particular interface, so adding setters for those properties is not an option.

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

My question is, how can I check the type cast here?

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

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

Thanks in advance!

提前致谢!

SOLUTION

解决方案

Thanks to the answer from @drobert, here is my updated code:

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

采纳答案by drobert

You can't. Due to type erasure, reflection will show you have an instance of HashMap, but the types are dropped at runtime. Effectively, you have HashMap< Object,Object >.

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

That said, you still have some options, and some advice I'd suggest you take. Among them:

也就是说,您仍然有一些选择,我建议您采纳一些建议。他们之中:

  • Check to see if it's an instance of 'Map' rather than 'HashMap'. It will make your API much more flexible since you most likely only care that you have rapid access by key rather than any particular impementation
  • Take advantage of java.util.Map's api which defines 'containsKey(Object)' and 'get(Object)', so you can still use mapInst.get("stringKey") safely, even without having to cast.
  • You can't ensure all values are strings, but you can take advantage of java.lang.Object's toString() method and obtain a String for each value regardless.
  • 检查它是否是“Map”而不是“HashMap”的实例。这将使您的 API 更加灵活,因为您很可能只关心您是否可以通过密钥快速访问而不是任何特定的执行
  • 利用 java.util.Map 的 api,它定义了 'containsKey(Object)' 和 'get(Object)',因此您仍然可以安全地使用 mapInst.get("stringKey"),即使不必进行转换。
  • 您不能确保所有值都是字符串,但您可以利用 java.lang.Object 的 toString() 方法并无论如何获取每个值的字符串。

In short: treat this like any Map, and attempt to access the keys as Strings even without the cast, and attempt to utilize each value as a String by doing a null check then calling .toString() and you'll have a much safer implementation.

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

回答by false_memories

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

Now, you know the object is of the correct type - even a custom abstract class or otherwise.

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

回答by Masudul

You should use try-catch, where you call addHelper(Object)method. This will ensure your correct type of HashMap.

您应该使用 try-catch,在其中调用addHelper(Object)方法。这将确保您正确类型的HashMap.

      try{
        addHelper(hashMap);
        }
        catch(ClassCastException ex){
            System.out.println("Is not desired hashmap");
        }

回答by Hot Licks

It should be noted that the original routine is exactly equivalent to coding

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

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

The explicit (HashMap)cast cannot possibly throw an error, since it's guarded by the instanceof. The implicitly-supplied (String)casts will only throw an error if the values returned from the HashMap are not Strings (or nulls).

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

(By "exactly equivalent to" I mean that the same bytecode is produced.)

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