如何将List
如何将List
在阅读书籍《Java Generics and Collections》时,在使用通配符和super的部分,我遇到了一个例子。
public staticvoid copy(List super T> dst, List extends T> src) { for (int i = 0; i < src.size(); i++) { dst.set(i, src.get(i)); } }
这个方法被这样调用:
Collections.copy(objs, ints);
上述调用是有效的,它的解释如下:
引用如下:
这个调用是允许的,因为objs
的类型是List
,它是List super Number>
的子类型(因为Object
是Number
的超类型,符合通配符的要求),而ints
的类型是List
,它是List extends Number>
的子类型(因为Integer
是Number
的子类型,符合extends通配符的要求)。
我对List
如何成为List super Number>
的子类型有疑问。
这个问题的出现是因为在解释中提到了"List
问题的解决方法是将解释中的错误进行修正。正确的解释应该是List
以下是修正过后的解释:
也许你正在对这个描述进行研究。可以这样理解:List super Number>
表示它应该是一个列表,可以存储任何对象,只要该对象是Number的超类。因此,List
显然符合这个条件。但在解释中,它却说List
修正后的解释:
也许你正在对这个描述进行研究。可以这样理解:List super Number>
表示它应该是一个列表,可以存储任何对象,只要该对象是Number的超类。因此,List
显然符合这个条件。但在解释中,它却说List
是List super Number>
的子类型。
这个问题的出现是因为在解释中提到了"List
问题的解决方法是将解释中的错误进行修正。正确的解释应该是List
编译器如何理解这种行为?
编译器在处理泛型类型时会进行类型推断和类型检查,以确保类型安全。对于协变(covariant)和逆变(contravariant)的泛型类型,编译器会根据其定义进行推断和检查。
在Java中,使用通配符“? extends”表示协变,使用通配符“? super”表示逆变。协变表示一个类型是其子类型的一种特殊情况,而逆变表示一个类型是其超类型的一种特殊情况。
对于逆变的泛型类型,编译器会根据其定义来判断类型关系。例如,对于“List super Number>”这个泛型类型,可以将其理解为“List
编译器会根据这个定义来推断和检查代码中的类型关系。例如,如果有一个方法接受“List super Number>”类型的参数,可以传递一个“List
因此,编译器可以通过逆变的定义来理解和支持这种行为。这样可以确保代码在类型安全的前提下能够正确运行。
编译器通过逆变的定义来理解和支持逆变泛型类型的行为。逆变允许泛型类型的参数类型为指定类型或其超类型。编译器会根据这个定义来推断和检查代码中的类型关系,从而确保代码在类型安全的前提下能够正确运行。
在这个问题中,出现了对于(How List
现在,部分的代码"? super Number"的意思是"任何是Number的超类型的类型,包括Number本身"。只有两个这样的类型,Number和Object。
所以,List super Number>是一个抽象类型,其中包含List
但是List
Number是 super Number>的有效替代品吗?
它是一个有效的替代品,但是我对List
List
不。List