为什么可以强制转换泛型类?

cto*_*mek 3 java generics casting invariance

Java泛型是不变的,因此无法进行此类转换:

List<Object> li = (List<Object>)new ArrayList<Integer>();
Run Code Online (Sandbox Code Playgroud)

但是在下面的第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);

    }
}
Run Code Online (Sandbox Code Playgroud)

new*_*cct 5

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