如何确保Java对象的类型为Map <string,object =“”> </string,>

时间:2012-09-11 17:43:20

标签: java collections casting type-erasure

简短,一目了然的问题摘要(TLDR):如何确保Java Object的类型为Map<String, Object>


我有一个YAML文档String。我使用来自Map<String, Object>的SnakeYAML创建YAML,但在我再次阅读它之前它可能被篡改。我不想求助于PKI签名,即使Map<String, Object>值可能遍布整个地方,也足以看出YAML表示是否仍为Object。我关心的是类型,而不是内容。

那么:我如何确保Object确实属于Map<String, Object>类型?

以下是我试图绕过类型擦除的各种SuppressWarning:

Object yamlObject = yaml.load(someYamlDocumentAsString);
// I only want to proceed if this YAML object is a Map<String, Object>
if ((yamlObject instanceof Map<?, ?>)) {
  Map<?, ?> propertyMap = (Map<?, ?>) yamlObject;
  for (Entry<?, ?> propertyEntry : propertyMap.entrySet()) {
    // I am checking each key and throwing if it's not a "String"
    Object propertyKey = propertyEntry.getKey();
    if (!(propertyKey instanceof CharSequence)) {
      throw new BananaException("FIXME"); // FIXME
    }
  }
} else {
  throw new CoconutException("FIXME"); // FIXME
}

以上可以做得更好吗?

顺便说一下,我不认为Java有类似于C#的as关键字(来自MSDN:as运算符就像一个强制转换操作。但是,如果转换不可能,则返回null而不是引发异常。)?


在上面的代码之后,我可以安全地抑制警告:

@SuppressWarnings("unchecked")
Map<String, Object> aBeautifulAndCozyMap = (Map<String, Object>) propertyMap;

1 个答案:

答案 0 :(得分:1)

由于类型擦除,信息在运行时是未知的,因此没有其他方法可以检查它而不是instanceofgetClass().getName()getDeclaredField("...").getGenericType().getActualTypeArguments()

在我看来,你应该留在instanceof,因为它易于阅读,其他开发人员很容易理解你想做什么。

PS:我喜欢例外情况; - )