可能不应该在这种问题上死磕,但是还是想不明白:
代码来自《Effective Java》 第三版,32章
贴代码:
static <T> T[] toArray(T... args) {
return args;
}
static <T> T[] pickTwo(T a, T b, T c) {
switch(ThreadLocalRandom.current().nextInt(3)) {
case 0: return toArray(a, b);
case 1: return toArray(a, c);
case 2: return toArray(b, c);
}
throw new AssertionError(); // Can't get here
}
public static void main(String[] args) {
String[] attributes = pickTwo("Good", "Fast", "Cheap");
}
程序能够顺利通过编译,但是运行会报错。
报错原因为:pickTwo返回的类型为Objcet[]
类型,因此无法强制转换为String[]
类型。
但是:
Objcet[] obj=new String[1]();
String[] str=(String[])obj;
是能正确运行的。
按照擦除和编译的语法糖,代码应该被编译成这样:
public static void main(String[] args) {
String[] attributes = pickTwo("Good", "Fast", "Cheap");
}
static String[] pickTwo(Object a, Object b, Object c) {
switch(ThreadLocalRandom.current().nextInt(3)) {
case 0: return (String[])toArray(a, b);
case 1: return (String[])toArray(a, c);
case 2: return (String[])toArray(b, c);
}
throw new AssertionError(); // Can't get here
}
static String[] toArray(Object... args) {
return (String[])args;
}
这也是泛型出现的意义。
可是static <T> T[] pickTwo(T a, T b, T c) {
pickTwo明明根据传入类型告诉了编译器,需要返回T[]类型。
因此传入String
类型的代码不应该就返回String[]
么
可是书上和运行结果确实证明了pickTwo
方法确实始终返回了Objcet
类型。
这是因为泛型数组的特殊性么?是在想不通,望指点