HashMap<Integer, String> 存储 String[] (Atlassian Confluence)

HashMap<Integer, String> stores String[] (Atlassian Confluence)

所以我正在为 Atlassian Confluence 开发一个插件,在我的配置页面控制器中,我有一个 HashMap<Integer, String> 类型的 HashMap,我用 HTML 表单中的值填充。现在在提交表单后,我尝试使用 .get(key) 从 HashMap 中读取一个值并将其安全保存到一个字符串中。我收到此类型转换错误:java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.lang.String。所以我用调试器查看了这些值,果然我的 HashMap 包含包裹在长度为 1 的数组中的字符串,而不是简单的简单字符串:即使我的 HashMap 显然是用 Integer->String 类型定义的,并且对 String 的赋值没有任何明确的工作类型转换。这真的让我很困惑。我想这与自动反序列化 POST-Values 的 Atlassian 相关;在过去,这已经让我很头疼,因为没有合适的文档,而且神奇的背景转换有很多怪癖。真正让我感到困惑的是,HashMap 可以突然存储与定义类型不同的值,我认为 Java 将这种重点放在类型安全上是不可能的。是否有一些我不知道的反射 foo 可以做到这一点?还是我误解了 HashMaps 的本质?有人经历过类似的事情吗?我在 Java.

的编码方面经验不足

如果您将 hashmap 创建为 HashMap<Integer, String>() 但将其存储为 HashMap,则确实可以将其存储在其他类型中。

例如:

    HashMap map = new HashMap<Integer, String>();
    map.put(1, new String[]{"1", "2"});
    System.out.println(map.get(1));

这段代码执行没有任何错误。

所以我认为发生的事情是你将它存储为 HashMap 引用,被视为 HashMap<Object, Object> 并且因为没有关于你能够的实际泛型类型的运行时信息将其他类型的对象添加到此集合。

但是,如果您使用 HashMap<Integer, String> 引用同一个地图,那么当您调用 get() 时,它将失败,并出现您描述的异常:

    HashMap map = new HashMap<Integer, String>();
    map.put(1, new String[]{"1", "2"});
    System.out.println(map.get(1));
    System.out.println("got here");
    HashMap<Integer, String> otherRef = (HashMap<Integer, String>) map;
    System.out.println(otherRef.get(1)); //<-ClassCastException exception here