java为什么在下面的代码中没有抛出ArrayStoreException?
private static void genericArrayTest() {
ArrayList<? extends Exception>[] exceptionListArray = new ArrayList[10];
Object[] exceptionObjectListArray = exceptionListArray;
ArrayList<String> wrongArrayList = new ArrayList<String>();
wrongArrayList.add("String One");
ArrayList<NullPointerException> exceptionList = new ArrayList<>();
ArrayList rawList = new ArrayList();
exceptionListArray[0] = exceptionList;
//exceptionListArray[0] = wrongArrayList; // Compile error?
//exceptionListArray[0] = rawList;
exceptionObjectListArray[0] = wrongArrayList;
// No compile time error, there is no ArrayStoreException why ?
ArrayList<? extends Exception> list = exceptionListArray[0]; // No exception here as well ??
Exception e = list.get(0);
// Exception only when accessing data, why not ArrayStoreException when we stored wrong list ??
System.out.println();
}
有人能解释一下发生了什么事吗
谷歌搜索说下面的数组声明是允许的
但不是这个
ArrayList<Exception>[] exceptionListArray = new ArrayList<Exception>[10];
这两项声明有何分别;为什么一个不允许另一个
Creating an array to store generic types in Java讨论如何创建泛型数组。但这个问题不是关于如何创建泛型数组,而是关于为什么在运行时不抛出ArrayStoreException&;java中泛型数组创建语法的差异
# 1 楼答案
在Java中,泛型参数化没有一个类来区分它们:
这是因为泛型是用type erasure实现的,这意味着在编译期间,它们会被转换替换:
变成:
不会抛出
ArrayStoreException
,因为ArrayList<Exception>
和ArrayList<String>
在程序执行期间具有相同的类型不允许使用泛型数组,因为在执行期间无法对类型参数执行这些检查。(因为类型参数已经不存在了。)
当我们有了这个:
这叫做未经检查的转换
a
实际上是一个ArrayList[]
,一个存储任何ArrayList
的数组,但我们基本上说了“暂时假设它是一个ArrayList<Exception>[]
”。数组对象a
指向的仍然是ArrayList[]
请参见以下程序进行说明:
http://ideone.com/dfCZjy
输出: