[英]Down casting Object array to array of type parameter
GenericArrayCreationIsDisallowedInJava构造函数中的语句如何工作? 有人可以解释一下吗?
public class GenericArrayCreationIsDisallowedInJava<I> {
private I[] i;
public GenericArrayCreationIsDisallowedInJava(int n)
{
i = (I[]) new Object[n];//works and prints out "Created". How?
System.out.println("Created");
}
public static void main(String[] args) {
new GenericArrayCreationIsDisallowedInJava<String>(2);
String[] strs = (String[]) new Object[2]; // throws ClassCastException. When this statement doesn't work, how is the "(I[]) new Object[n]" statement working?
}
}
i = (I[]) new Object[n];
您对上述内容的看法尚不完全清楚,但最不明确的一件事是创建I
数组。 负责选择数组类型的唯一部分是在new
关键字之后:它是Object
的数组,不安全地强制转换为I[]
。
编译器必须允许该行进行编译,因为它对I
类型一无所知:它也可以是Object
,因此该行是合法的。
还要注意, I[]
的擦除类型是Object[]
: i
变量的实际类型(在字节码中)是Object[]
。 因此,无论实例使用哪种类型的参数,赋值都会在运行时成功完成。
仅当将数组分配回可更改的类型时,才会引发ClassCastException
。 例如:
GenericArrayCreationIsDisallowedInJava o =
new GenericArrayCreationIsDisallowedInJava<String>(2);
String[] strs = o.i; // ClassCastException thrown here
在类型擦除过程中,编译器将强制类型转换为String[]
插入分配strs
的行中。 这表明需要防止i
泄漏到正在使用它的类之外。
要了解发生了什么,只需在类型擦除之后考虑相同的代码即可(只需删除类型参数并在必要时插入强制类型转换):
public class GenericArrayCreationIsDisallowedInJava {
private Object[] i;
public GenericArrayCreationIsDisallowedInJava(int n)
{
i = (Object[]) new Object[n];//works and prints out "Created". How?
System.out.println("Created");
}
public static void main(String[] args) {
new GenericArrayCreationIsDisallowedInJava(2);
String[] strs = (String[]) new Object[2]; // throws ClassCastException. When this statement doesn't work, how is the "(I[]) new Object[n]" statement working?
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.