答案 0 :(得分:9)
不允许使用不可恢复的组件类型创建数组。
实际上意味着通用数组创建是非法的:
new T[...] // prohibited
不允许使用通用数组,因为数组在运行时包含有关其组件的信息。对于泛型而言,情况并非如此。泛型在编译器级别实现。因此,在创建数组时必须事先知道组件类型。
答案 1 :(得分:4)
Java编程语言不允许创建参数化类型的数组,即不允许新的T []
如果数组的元素类型不可恢复(第4.7节),则虚拟机无法执行前一段中描述的存储检查。这就是为什么禁止创建不可再生类型的数组的原因。可以声明其元素类型不可重新生成的数组类型的变量,但是任何为它们赋值的尝试都会产生未经检查的警告(第5.1.9节)。
您可以详细了解here 查看更多:
下面是代码示例,它显示了使用泛型类型的varargs时可能出现的问题。
public class ArrayBuilder {
public static <T> void addToList(List<T> listArg, T... elements) {
for (T x : elements) {
listArg.add(x);
}
}
public static void faultyMethod(List<String>... l) {
Object[] objectArray = l; // Valid
objectArray[0] = Arrays.asList(42);
String s = l[0].get(0); // ClassCastException thrown here
}
public static void main(String[] args) {
List<String> stringListA = new ArrayList<String>();
List<String> stringListB = new ArrayList<String>();
ArrayBuilder.addToList(stringListA, "Seven", "Eight", "Nine");
ArrayBuilder.addToList(stringListA, "Ten", "Eleven", "Twelve");
List<List<String>> listOfStringLists = new ArrayList<List<String>>();
ArrayBuilder.addToList(listOfStringLists, stringListA, stringListB);
ArrayBuilder.faultyMethod(Arrays.asList("Hello!"),
Arrays.asList("World!"));
}
}
当编译器遇到varargs方法时,它会将varargs形式参数转换为数组。但是,the Java programming language does not permit the creation of arrays of parameterized types
。在方法ArrayBuilder.addToList中,编译器将varargs形式参数T...
元素转换为形式参数T[]
元素。但是,由于类型擦除,编译器会将varargs
形式参数转换为Object[]
元素。因此,存在堆污染的可能性。
以下语句将varargs形式参数l
分配给Object数组objectArgs:
Object[] objectArray = l;
此声明可能会引入堆污染。与varargs形式参数l的参数化类型匹配的值可以分配给变量objectArray,因此可以分配给l。但是,编译器不会在此语句中生成未经检查的警告。编译器在将varargs形式参数List<String>
... l转换为形式参数List[]
时已生成警告。本声明有效;变量l的类型为List[]
,它是Object[]
的子类型。
因此,如果将任何类型的List对象分配给objectArray数组的任何数组组件,编译器不会发出警告或错误,如下所示:
objectArray[0] = Arrays.asList(42);
此语句使用包含一个Integer类型的对象的List对象分配给objectArray数组的第一个数组组件。
假设您使用以下语句调用ArrayBuilder.faultyMethod:
ArrayBuilder.faultyMethod(Arrays.asList("Hello!"), Arrays.asList("World!"));
在运行时,JVM会在以下语句中抛出ClassCastException:
// ClassCastException thrown here
String s = l[0].get(0);
答案 2 :(得分:3)
如果您在该链接中进一步阅读,您会发现以下声明: -
Pair<String,String> is not a reifiable type, that is, it loses information as a
result of type erasure and is at runtime represented as the raw type Pair
instead of the exact type Pair<String,String>
来自JLS - Arrays的更多内容: -
<强>讨论强>
如果数组的元素类型不可恢复(第4.7节),则为虚拟 机器无法执行前面描述的存储检查 段。这就是为什么要创建不可再生类型的数组的原因 禁止。可以声明其元素的数组类型的变量 type是不可恢复的,但是任何为它们赋值的尝试都会 引起一个未经检查的警告(§5.1.9)。