Java泛型数组:为什么要编译,这意味着什么?

Java泛型数组:为什么要编译,这意味着什么?,java,arrays,generics,Java,Arrays,Generics,Java不允许直接创建泛型数组。我知道由于擦除,泛型类型在运行时是未知的,而数组需要在运行时进行类型检查,因此两者不兼容 这段代码不能编译- Holder[]整数=新的Holder[5]; 很好,但我不确定这段代码为什么会编译(带有不安全类型转换的警告) 持有人[]持有人=新持有人[5]; 持有人[0]=新持有人(5); 持有人[1]=新持有人(5); 持有人[2]=新持有人(5); 我不太明白我到底是怎么通过去掉菱形括号来欺骗编译器的。这是创建泛型数组的一种可接受的方法吗 此外,当我将这一

Java不允许直接创建泛型数组。我知道由于擦除,泛型类型在运行时是未知的,而数组需要在运行时进行类型检查,因此两者不兼容

这段代码不能编译-

Holder[]整数=新的Holder[5];
很好,但我不确定这段代码为什么会编译(带有不安全类型转换的警告)

持有人[]持有人=新持有人[5];
持有人[0]=新持有人(5);
持有人[1]=新持有人(5);
持有人[2]=新持有人(5);
我不太明白我到底是怎么通过去掉菱形括号来欺骗编译器的。这是创建泛型数组的一种可接受的方法吗

此外,当我将这一行添加到代码-
holders[3]=newholder(“Hello”)
它抛出编译错误
Holder无法转换为Holder
我觉得这很奇怪,因为据我所知,不允许泛型数组的整个想法是因为由于类型擦除,数组无法区分两种不同的泛型类型。但在本例中,编译器可以检测不正确的类型转换

我在这里遗漏了什么?

在上,您可以清楚地看到为什么不允许创建泛型类型的数组:

Object[] stringLists = new List<String>[];  // compiler error, but pretend it's allowed
stringLists[0] = new ArrayList<String>();   // OK
stringLists[1] = new ArrayList<Integer>();  // An ArrayStoreException should be thrown,
                                            // but the runtime can't detect it.
Object[]stringLists=新列表[];//编译器错误,但假设它是允许的
StringList[0]=新的ArrayList();//好啊
StringList[1]=新的ArrayList();//应引发ArrayStoreException,
//但是运行时无法检测到它。
stringlist
应该只能存储
List
,但是通过使用上述代码,我不仅可以欺骗编译器,还可以欺骗运行时,由于类型擦除,允许我将
ArrayList
存储到
stringlist

但我不确定这段代码为什么要编译

嗯,因为
Holder
是原始类型。看见就编译器和运行时而言,创建一个原始类型的数组是非常好的,因为这里你不是说“这个数组只能存储
Holder
”,你只是说“这个数组只能存储
Holder
(任何东西)”

这是创建泛型数组的一种可接受的方法吗

嗯,从技术上讲,你的数组不是通用的。我可以将它分配给
Holder[]
并将
Holder
分配给它的一个元素,并且不会发生异常或编译器错误。就编译器而言,这是“可以接受的”,但由于您失去了类型安全性,我不建议您使用它。您应该使用类似于
ArrayList
的内容

我觉得这很奇怪,因为据我所知,不允许泛型数组的整个想法是因为由于类型擦除,数组无法区分两种不同的泛型类型。但在本例中,编译器可以检测不正确的类型转换


编译器可以检测到它,不是因为数组不允许您放入
Holder
,而是因为变量的编译时类型是
Holder[]
。编译器仍然可以通过查看编译时类型来检查类型,但一旦您丢失了编译时类型(将其分配给
Object[]
Holder[]
类型的变量),它就无法为您执行此操作。数组本身首先允许任何类型的
Holder
,因为它是
Holder[]

,关键是您可以编写
((Holder[])Holder)[0]=新的Holder(“”
),这不会失败(这里:当您试图从
Holder[0]
中获取
整数时,它会失败)。
Object[] stringLists = new List<String>[];  // compiler error, but pretend it's allowed
stringLists[0] = new ArrayList<String>();   // OK
stringLists[1] = new ArrayList<Integer>();  // An ArrayStoreException should be thrown,
                                            // but the runtime can't detect it.