【发布时间】:2020-06-30 04:45:52
【问题描述】:
我知道泛型类型和参数化类型之间的一般区别,并且我知道一些一般规则:
-
Object[] 不能转换为 String[],除非 Object[] 数组是使用 new String[n] 构造的。
但我的问题有点具体。所以我要给出一些代码。
根据上述一般规则,以下2个例子中的强制转换无效:
static List<String> f1a(List<String> list) {
return List.of((String[]) list.toArray()); // ClassCastException
}
static List<String> f2a(List<String> list) {
return (List<String>) List.of(list.toArray()); // compile-time error: Inconvertible types
}
现在,如果我将 String 类型替换为泛型类型参数 E,则强制转换有效!但是我真的不明白为什么?
// f1 is a generic version f1a, where String -> E
static <E> List<E> f1(List<E> list) {
return List.of((E[]) list.toArray());
}
// f2 is a generic version f2a, where String -> E
static <E> List<E> f2(List<E> list) {
return (List<E>) List.of(list.toArray());
}
下面的demo表明f1和f2是有效的,而f1a和f2a是有问题的:
public static void main(String[] args) {
List<String> list = List.of("hello", "world");
List<String> copy1 = f1(list); // works
System.out.println(copy1);
List<String> copy2 = f2(list); // works
System.out.println(copy2);
List<String> copy1a = f1a(list); // ClassCastException
System.out.println(copy1a);
List<String> copy2a = f2a(list); // compile-time error
System.out.println(copy2a);
}
【问题讨论】:
-
那些是不安全的强制转换。如果你启用所有编译器警告,编译器会告诉你它们不安全。