简体   繁体   English

为什么android studio会警告我有关为输入项创建通用数组的信息

[英]Why does android studio warn me about generic array creation for typed entry

I have an adapter in my android project which takes in a reusable map and for simplicity keeps an array of its data to use. 我的android项目中有一个适配器,它带有一个可重用的地图,为简单起见,保留了要使用的数据数组。

private Entry<String, String>[] mData;

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

Now I wanted to make it a little more efficient and get rid of the unchecked warning, so I changed to using a specific array type 现在,我想使其效率更高一些,并消除未经检查的警告,因此我改为使用特定的数组类型

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

However the new Entry<String, String>[ data.size() ] part is now flagged " Generic array creation " with no further information. 但是, new Entry<String, String>[ data.size() ]部分现在标记为“ 通用数组创建 ”,没有更多信息。 Why is this illegal? 为什么这是非法的?

I understand that Java has Type erasure and that generics result in different types (such as explained here ), but the above line of code still seems like it should be legal to me. 据我所知,Java有类型擦除和仿制药导致不同类型(如解释在这里 ),但上面的代码行似乎仍像它应该是合法的我。

Why is this illegal? 为什么这是非法的?

Because arrays are covariant. 因为数组是协变的。 Suppose you were able to compile the following code: 假设您能够编译以下代码:

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();

At runtime, an ArrayStoreException would not be thrown by the assignment because AbstractMap.SimpleEntry (the runtime type of AbstractMap.SimpleEntry<Integer, Integer> ) is covariant with Map.Entry (the runtime type of Entry<String, String> ) - but it would then fail with a ClassCastException when you try to execute the last line because they key is an Integer , not a String . 在运行时,一个ArrayStoreException就不会被分配抛出因为AbstractMap.SimpleEntry (的运行时类型AbstractMap.SimpleEntry<Integer, Integer> )是协变与Map.Entry (的运行时类型Entry<String, String> ) -但当您尝试执行最后一行时,它将失败并显示ClassCastException ,因为它们的键是Integer而不是String

However, you now have to worry about every element potentially being of the wrong type - given a reference to a Entry<String, String>[] , you can't know exactly how the array was initialized or updated, so accessing any given element in the wrong way could result in a runtime exception. 但是,您现在必须担心每个元素的类型可能都不正确-给出对Entry<String, String>[]的引用,您无法确切知道数组的初始化或更新方式,因此访问任何给定元素错误的方式可能导致运行时异常。

(When I say "the wrong way", I am constrasting String key = array[0].getKey() with something like invoking something like array[0].toString() - all objects have a toString() method, so that would not attempt a cast). (当我说“错误的方式”时,我通过调用诸如array[0].toString()类的东西来约束String key = array[0].getKey() array[0].toString() -所有对象都有一个toString()方法,因此不会尝试强制转换)。

The safest way to avoid such a situation is simply to make creation of generic arrays illegal. 避免这种情况的最安全方法就是简单地使通用数组的创建非法。

Note that this is different from the case of non-generic-but-covariant arrays: 请注意,这与非泛型但协变量数组的情况不同:

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

Because that assignment would throw an ArrayStoreException , a value of the wrong type can never be added to the array. 因为该分配将引发ArrayStoreException ,所以永远不能将错误类型的值添加到数组中。

As such, although you still have to worry about an ArrayStoreException when trying to put a value into the array, you don't have to worry about ClassCastException s when reading a value from the array. 这样,尽管在尝试将值放入数组时仍然需要担心ArrayStoreException从数组中读取值时不必担心ClassCastException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM