java - 为什么 android studio 会警告我有关类型化条目的通用数组创建的问题

标签 java android generics

我的 Android 项目中有一个适配器,它接受可重用的 map ,并为了简单起见保留了一个要使用的数据数组。

private Entry<String, String>[] mData;

public MyAdapter(@NonNull Map<String, String> data) {
    mData = (Entry<String, String>[]) data.entrySet().toArray();
}

现在我想让它更高效一点,并摆脱未经检查的警告,所以我改为使用特定的数组类型

mData = data.entrySet().toArray( new Entry<String, String>[ data.size() ] );

但是new Entry<String, String>[ data.size() ]部分现在被标记为“通用数组创建”,没有更多信息。 为什么这是非法的?

我知道 Java 具有类型删除功能,并且泛型会导致不同的类型(例如解释的 here ),但上面的代码行对我来说仍然应该是合法的。

最佳答案

Why is this illegal?

因为数组是协变的。假设您能够编译以下代码:

Entry<String, String>[] array = new Entry<String, String>[ isoMap.size() ];
Object[] objArray = array;

// Does not throw an ArrayStoreException.
objArray[0] = new AbstractMap.SimpleEntry<>(Integer.valueOf(0), Integer.valueOf(0));
String key = array[0].getKey();

在运行时,ArrayStoreException赋值不会抛出异常,因为 AbstractMap.SimpleEntry ( AbstractMap.SimpleEntry<Integer, Integer> 的运行时类型)与 Map.Entry 协变(运行时类型 Entry<String, String> ) - 但它会失败并显示 ClassCastException当您尝试执行最后一行时,因为它们的键是 Integer ,不是String .

但是,您现在必须担心每个元素都可能属于错误类型 - 给出对 Entry<String, String>[] 的引用。 ,您无法确切知道数组是如何初始化或更新的,因此以错误的方式访问任何给定元素可能会导致运行时异常。

(当我说“错误的方式”时,我将 String key = array[0].getKey() 与调用类似 array[0].toString() 之类的东西进行对比 - 所有对象都有一个 toString() 方法,因此不会尝试强制转换)。

避免这种情况的最安全方法就是使泛型数组的创建非法。

请注意,这与非泛型但协变数组的情况不同:

String[] array = new String[1];
Object[] objArray = array;
// Throws an ArrayStoreException.
objArray[0] = Integer.valueOf(0);

因为该赋值会抛出 ArrayStoreException ,错误类型的值永远不能添加到数组中。

因此,尽管您仍然需要担心 ArrayStoreException当尝试将值放入数组时,您不必担心 ClassCastException s 从数组读取值时。

关于java - 为什么 android studio 会警告我有关类型化条目的通用数组创建的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35649951/

相关文章:

java - 收到错误 HTTP 状态 405 - 此 URL 不支持 HTTP 方法 GET 但从未使用过 `get`?

java - 如何查看优先级队列的容量?

android - 带有 HttpsURLConnection 的 ClassCastException

android - 来自 Android 设备 (3G) 和 whatismyip.com 的不同 IP?

C# 泛型 - 我可以将此类变成泛型吗?

java - 如何以通用方式访问 Java 构造函数?

java - SONAR 实现是否将伴随类视为公共(public)类的一部分 - 指标

java - Java Streams 是迭代器设计模式的实现吗?

android - 在android TextView中右对齐文本

java - 是否可以使泛型方法签名实现泛型+接口(interface)?