gpt4 book ai didi

java - 需要有关创建通用数组的帮助

转载 作者:行者123 更新时间:2023-11-30 07:42:31 25 4
gpt4 key购买 nike

我有一行可以编译并运行的代码:

HashMap<String, Object>[] resultArray = 
new ObjectMapper().readValue(json, HashMap[].class);

它使用 Jackson ObjectMapper .

我还有另一行,它给出了通用数组创建错误:

HashMap<String, Object>[] resultArray = new HashMap<String, Object>[] { resultObject };

我知道在 Java 中不可能做到这一点。但显然 readValue() 以某种方式做到了。怎么可能?

最佳答案

readValue 创建了一个原始类型的数组 HashMap[] -- 不是 HashMap<String, Object>[] 。原始类型是一个相对较低级别、大部分已过时的功能,您应该尽可能避免使用;但对于某些事情,比如反射( jackson 严重依赖反射),这通常是不可能的。

缺点是 jackson 正在使用一个危险的工具。与许多危险工具一样,它并不总是会造成损害;而是会造成损害。它可能造成损坏,因此应谨慎使用并具有一定的经验。

危险本质上归结为这样一个事实:对于原始类型,编译器无法跟踪您想要使用的实际参数化类型;这意味着它无法防止您错误地使用它们。

在某些时候,您可能会将此原始数组转换为通用数组;像这样:

HashMap[] original = new HashMap[0];
HashMap<String,Object>[] publiclyVisible = original;
// or
@SuppressWarnings("unchecked")
HashMap<String,Object> singleElement = original[0];

因为erasure ,实际上 JVM 中没有任何东西可以跟踪 publiclyVisible旨在保存 HashMap<String, Object> 的数组s。 JVM 所知道的只是它保存了一个原始数组 HashMap s。因此,如果您输入 Map<Integer, Foo>进入original ,JVM会让你;如果后来有人将其检索为 Map<String, Object> ,JVM 也会很高兴地允许这样做。只有当有人尝试使用这些类型时,他们才会遇到麻烦,而且是以一种非常不明显的方式。例如,也许他们会这样做:

Map<String, Object> myMap = publiclyVisible[0];
for (String key : myMap.keySet()) {
...

...他们会得到一个 ClassCastException for行,说 Integer 不能转换为 String。这很令人困惑!问题是 JVM 已经删除了类型信息,因此它无法跟踪任何不正确的数组内容。它第一次检测到有问题是在它转换第一个 myMap 的引用时。 key — 这是一个整数,因为这意外地是 HashMap<Integer, Foo> — 到一个字符串。本质上,程序员期望 myMap的键都是字符串,但是删除和原始类型共同允许它们是任何类型。

该问题还有其他变体,以及其他令人困惑的触发方式;但它们都归结为同一个基本问题。简而言之,删除意味着 JVM 无法跟踪引用的实际类型,而原始类型意味着编译器也无法跟踪它们,当您将它们组合起来时,可能会增加出现令人困惑的错误的可能性。

关于java - 需要有关创建通用数组的帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34460539/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com