如何检查 Object 是否是 instanceof HashMap<?,?>[] in Java?

How to check if Object is instanceof HashMap<?,?>[] in Java?

我在 java 中有一个 HashMap 数组

HashMap<String, String>[] convertTags = new HashMap[1];
HashMap<String, String> tag = new HashMap<>();
tag.put("key", "test-tag");
tag.put("value", "test-value");
convertTags[0] = tag;

在另一个 class 中,我将此 convertTags 对象传递给一个接受通用对象的函数。根据对象的类型,我想 运行 不同的代码。但是,当我有一个 if 语句来检查 HashMap 数组的实例时,它似乎无法识别我的 convertTags 对象。

public static void function (Object obj) {
...
   if (obj instanceof HashMap<?, ?>[]) {
      //do stuff
   }
}

我错过了什么吗?在 convertTags 对象上调用 .getClass() returns class [Ljava.util.HashMap;

使用 instanceof 进行类型检查时,您不能使用通用类型作为检查:您必须使用原始类型。原因很简单:大部分泛型类型信息在编译时被删除,在 运行 时不再存在。对于 运行 时代的 JVM,这些类型是相同的:List<T>List<String>List<Hashmap<E>>List。如果 Java 允许对 instanceof 操作使用通用类型,可能会导致严重的类型错误。

事实上,允许这样的操作并不严格正确:

if (obj instanceof Hashmap<?,?>[]) { ...

编译器允许这样做,因为无界通配符类型是 Java 中存在的唯一 具体化 泛型类型。许多作者不鼓励在这种情况下使用无限通配符,因为它们可能暗示使用其他(不可具体化的)泛型类型是有效的。相反,这是最好使用原始类型的不常见情况:

if (obj instanceof Hashmap[]) { ...
    Hashmap<?,?>[] map = (Hashmap<?,?>[]) obj
        :
        :

因为类型已经过检查,转换是合法的,上面的代码片段不会发出编译器警告。

如果 运行-time 需要有关 Hashmap 中类型的信息,您可以考虑两种方法(可以混合使用):

  • 生成 function() 以获取键 and/or 值的类型参数
  • 传递 Class<T> 个对象作为 运行 次 类型标记 键和值的类型。