为什么可以转换泛型 class?
Why is it possible to cast generic class?
Java 泛型是不变的,所以不可能进行这样的转换:
List<Object> li = (List<Object>)new ArrayList<Integer>();
但是在第 4 行的以下代码中,我可以从 List<Integer>
转换为 List<T>
,其中 T
可以是任何类型。为什么允许这种类型的转换?
我知道它会生成关于未经检查的转换的警告,但要点是这种转换在参数化方法中是可能的,但在普通代码中是不可能的。请记住,泛型是不变的,为什么它被允许?在具有 List<Integer>
的正常代码中,我只能将其转换为 List<Integer>
这没有意义,其他转换是非法的。那么允许第 4 行中的强制转换有什么意义呢?
我知道泛型类型在编译时被删除,它以 List xlist = (List)list
结尾,但在删除这些类型之前,很明显这种转换不应该被允许,除非它只在某些情况下被接受将 Integer 作为 el
传递,这没有多大意义。
class Test {
public static <T> void t(List<Integer> list, T el) {
List<T> xlist = (List<T>)list; //OK
xlist.add(el);
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
t(list, "a");
t(list, "b");
//prints [a, b] even if List type is Integer
System.out.println(list);
}
}
我想答案是这种转换是可能的,因为 Integer
可以作为参数 el
传递,在这种情况下转换是正确的。在 Integer 以外的所有其他类型的情况下,它将被非法转换。但是正如我在泛型中看到的那样,如果至少有一种类型可以给出正确的转换(Integer
),那么编译器不会给出错误,而是警告,即使所有其他情况都无效。
在 Java 中,执行在编译时已知始终不正确或始终正确的显式转换是编译错误。从 List<Integer>
到 List<Object>
的转换在编译时已知总是不正确的,因此不允许。从 List<Integer>
到 List<T>
的转换在编译时并不知道总是不正确的——如果 T
是 Integer
并且 T
是编译时未知。
对象是 class 整数的超 class。 List<Object>
不是 class List<Integer>
的超级 class ,但是如果你想 List<Object>
引用 List<Integer>
你可以使用小丑符号 (?)。
List<?> list1 = new List<Object>();
List<?> list2 = new List<Integer>();
list1 = list2;
Java 泛型是不变的,所以不可能进行这样的转换:
List<Object> li = (List<Object>)new ArrayList<Integer>();
但是在第 4 行的以下代码中,我可以从 List<Integer>
转换为 List<T>
,其中 T
可以是任何类型。为什么允许这种类型的转换?
我知道它会生成关于未经检查的转换的警告,但要点是这种转换在参数化方法中是可能的,但在普通代码中是不可能的。请记住,泛型是不变的,为什么它被允许?在具有 List<Integer>
的正常代码中,我只能将其转换为 List<Integer>
这没有意义,其他转换是非法的。那么允许第 4 行中的强制转换有什么意义呢?
我知道泛型类型在编译时被删除,它以 List xlist = (List)list
结尾,但在删除这些类型之前,很明显这种转换不应该被允许,除非它只在某些情况下被接受将 Integer 作为 el
传递,这没有多大意义。
class Test {
public static <T> void t(List<Integer> list, T el) {
List<T> xlist = (List<T>)list; //OK
xlist.add(el);
}
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
t(list, "a");
t(list, "b");
//prints [a, b] even if List type is Integer
System.out.println(list);
}
}
我想答案是这种转换是可能的,因为 Integer
可以作为参数 el
传递,在这种情况下转换是正确的。在 Integer 以外的所有其他类型的情况下,它将被非法转换。但是正如我在泛型中看到的那样,如果至少有一种类型可以给出正确的转换(Integer
),那么编译器不会给出错误,而是警告,即使所有其他情况都无效。
在 Java 中,执行在编译时已知始终不正确或始终正确的显式转换是编译错误。从 List<Integer>
到 List<Object>
的转换在编译时已知总是不正确的,因此不允许。从 List<Integer>
到 List<T>
的转换在编译时并不知道总是不正确的——如果 T
是 Integer
并且 T
是编译时未知。
对象是 class 整数的超 class。 List<Object>
不是 class List<Integer>
的超级 class ,但是如果你想 List<Object>
引用 List<Integer>
你可以使用小丑符号 (?)。
List<?> list1 = new List<Object>();
List<?> list2 = new List<Integer>();
list1 = list2;