有人可以解释以下语句的含义:
不允许创建具有不可具体化组件类型的数组。
不允许创建具有不可具体化组件类型的数组。
实际上意味着创建通用数组是非法的:
new T[...] // prohibited
不允许使用通用数组,因为数组在运行时包含有关其组件的信息。这不适用于泛型。泛型在编译器级别实现。因此,在创建数组时必须事先知道组件类型。
Java 编程语言不允许创建参数化类型的数组,即不允许创建 new T []
如果数组的元素类型不可具体化(第 4.7 节),则虚拟机无法执行上一段中描述的存储检查。这就是为什么禁止创建不可具体化类型的数组的原因。可以声明其元素类型不可具体化的数组类型的变量,但任何试图为它们赋值的尝试都会引发未经检查的警告(第 5.1.9 节)。
你可以在这里阅读更多关于它的信息 查看更多:
下面是代码示例,它显示了如果您将可变参数与泛型类型一起使用会出现什么问题。
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!"));
}
}
当编译器遇到可变参数方法时,它会将可变参数形式参数转换为数组。然而,the Java programming language does not permit the creation of arrays of parameterized types
. 在方法 ArrayBuilder.addToList 中,编译器将 varargs 形参T...
元素转换为形参T[]
元素,一个数组。但是,由于类型擦除,编译器将varargs
形式参数转换为Object[]
元素。因此,存在堆污染的可能性。
以下语句将可变参数形式参数分配给l
Object 数组 objectArgs:
Object[] objectArray = l;
此语句可能会引入堆污染。与可变参数形式参数 l 的参数化类型匹配的值可以分配给变量 objectArray,因此可以分配给 l。但是,编译器不会在此语句处生成未经检查的警告。List<String>
编译器在将可变参数形式参数... l 转换为形式参数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);
如果您在该链接中进一步阅读,您会发现以下声明:-
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 - 阵列:-
讨论
如果数组的元素类型不可具体化(第 4.7 节),则虚拟机无法执行上一段中描述的存储检查。这就是为什么禁止创建不可具体化类型的数组的原因。可以声明其元素类型不可具体化的数组类型的变量,但任何试图为它们赋值的尝试都会引发未经检查的警告(第 5.1.9 节)。