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?
}
}
答案 0 :(得分:4)
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
。这表明需要让{{1}}不要“泄漏”在正在使用它的类之外。
答案 1 :(得分:1)
要了解发生了什么,只需在类型擦除后考虑相同的代码(只需删除类型参数并在必要时插入强制转换):
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?
}
}