3

Java 泛型是不变的,所以不可能进行这样的转换:

List<Object> li = (List<Object>)new ArrayList<Integer>();

但是在第 4 行的以下代码中,我可以转换 from List<Integer>to 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);

    }
}
4

3 回答 3

5

在 Java 中,执行显式转换是编译错误,在编译时已知该转换始终不正确或始终正确。从List<Integer>to的转换List<Object>在编译时已知总是不正确的,因此是不允许的。从List<Integer>toList<T>的强制转换在编译时并不知道总是不正确的——如果T是是正确的Integer,并且T在编译时不知道。

于 2016-05-20T01:04:06.383 回答
1

我想答案是这种转换是可能的,因为Integer它可以作为参数传递el,在这种情况下,转换是正确的。在除 Integer 之外的所有其他类型的情况下,它将被非法强制转换。但正如我在泛型中看到的那样,如果至少有一种类型会给出正确的强制转换 ( Integer),那么即使所有其他情况都无效,编译器也不会给出错误,而是警告。

于 2016-05-19T20:17:08.307 回答
0

Object 是 Integer 类的超类。List<Object>不是该类的超类List<Integer>,但此外,如果您想List<Object>引用 aList<Integer>您可以使用百搭符号 (?)。

List<?> list1 = new List<Object>();
List<?> list2 = new List<Integer>();
list1 = list2;
于 2020-03-23T20:50:30.610 回答