List之间有什么区别
我以前用
List
我喜欢@Bert F给出的答案,但我的大脑就是这么看的。
我手里有个X如果我想把我的X写成一个列表,那个列表需要是一个列表,或者是一个列表,当我写它们的时候,我的X可以上升到列表,也就是说,任何一个超类...
List<? super X>
如果我得到一个列表,我想从列表中读出一个X,那最好是一个X的列表,或者一个在我读出时可以向上转换为X的东西的列表,即任何扩展X的东西
List<? extends X>
希望这有帮助。
想象一下有这样的等级制度
通过写作
List<? extends C2> list;
您的意思是,list
将能够引用类型为(例如)ArrayList
的对象,其泛型是C2
的7个子类型之一(C2
包括在内):
新建阵列列表
等等。七个不同的案例:
1) new ArrayList<C2>(): can store C2 D1 D2 E1 E2 E3 E4
2) new ArrayList<D1>(): can store D1 E1 E2
3) new ArrayList<D2>(): can store D2 E3 E4
4) new ArrayList<E1>(): can store E1
5) new ArrayList<E2>(): can store E2
6) new ArrayList<E3>(): can store E3
7) new ArrayList<E4>(): can store E4
对于每种可能的情况,我们有一组“可存储”类型:这里用图形表示的7个(红色)集合
正如你所看到的,没有一种安全类型是常见的每种情况下:
您不能列表。添加(新C2(){})
list=new ArrayList
等等。
通过写作
List<? super C2> list;
您的意思是,
list
将能够引用类型为ArrayList
的对象,其泛型是C2
的7个超类型之一(包括C2
):
A1:新建阵列列表
等等。七个不同的案例:
1) new ArrayList<A1>(): can store A1 B1 B2 C1 C2 D1 D2 E1 E2 E3 E4
2) new ArrayList<A2>(): can store A2 B2 C1 C2 D1 D2 E1 E2 E3 E4
3) new ArrayList<A3>(): can store A3 B3 C2 C3 D1 D2 E1 E2 E3 E4
4) new ArrayList<A4>(): can store A4 B3 B4 C2 C3 D1 D2 E1 E2 E3 E4
5) new ArrayList<B2>(): can store B2 C1 C2 D1 D2 E1 E2 E3 E4
6) new ArrayList<B3>(): can store B3 C2 C3 D1 D2 E1 E2 E3 E4
7) new ArrayList<C2>(): can store C2 D1 D2 E1 E2 E3 E4
对于每种可能的情况,我们有一组“可存储”类型:这里用图形表示的7个(红色)集合
如你所见,这里我们有七种常见的保险类型:
C2
,D1
,D2
,E1
,E2
,E3
,E4
。
你可以列表。添加(新C2(){})
因为,无论我们引用的是哪种列表,C2
都是允许的
等等。您可能注意到这些类型对应于从类型
C2
开始的层次结构。
这里是完整的层次结构,如果你想做一些测试
interface A1{}
interface A2{}
interface A3{}
interface A4{}
interface B1 extends A1{}
interface B2 extends A1,A2{}
interface B3 extends A3,A4{}
interface B4 extends A4{}
interface C1 extends B2{}
interface C2 extends B2,B3{}
interface C3 extends B3{}
interface D1 extends C1,C2{}
interface D2 extends C2{}
interface E1 extends D1{}
interface E2 extends D1{}
interface E3 extends D2{}
interface E4 extends D2{}
列表的通配符声明
List<? extends Number> foo3 = new ArrayList<Number>(); // Number "extends" Number (in this context)
List<? extends Number> foo3 = new ArrayList<Integer>(); // Integer extends Number
List<? extends Number> foo3 = new ArrayList<Double>(); // Double extends Number
>
您可以读取Number
,因为可以分配给fo3
的任何列表都包含一个Number
或Number
的子类。
- 你不能读取
整数
,因为fo3
可能指向一个List
书写-鉴于上述可能的分配,您可以向
列表foo3
中添加哪些类型的对象,这些对象对于上述所有可能的数组列表
分配都是合法的:
你不能添加一个整数
,因为fo3
可能指向一个List
你不能添加任何对象到
List
现在考虑<代码>列表
列表的通配符声明
List<? super Integer> foo3 = new ArrayList<Integer>(); // Integer is a "superclass" of Integer (in this context)
List<? super Integer> foo3 = new ArrayList<Number>(); // Number is a superclass of Integer
List<? super Integer> foo3 = new ArrayList<Object>(); // Object is a superclass of Integer
>
你不能保证一个整数
,因为fo3
可能指向一个List
书写-鉴于上述可能的分配,您可以向
列表foo3
中添加哪些类型的对象,这些对象对于上述所有可能的数组列表
分配都是合法的:
您可以添加整数
,因为在上面的任何列表中都允许整数
。
- 您可以添加
整数
子类的实例,因为在上面的任何列表中都允许整数
子类的实例。 - 你不能添加一个
Double
,因为fo3
可能指向一个ArrayList
记住PECS:“生产者延伸,消费者超级”。
>
“Consumer Super”-如果你需要一个
列表
来消费T
值(你想在列表中写入T
s),你需要用声明它?超级T
,例如列表
如果需要对列表进行读写操作,则需要准确地声明它,而不使用通配符,例如
list
请注意Java泛型FAQ中的这个例子。注意源列表
src
(生产列表)如何使用extends
,目标列表dest
(消费列表)如何使用super
:
public class Collections {
public static <T> void copy(List<? super T> dest, List<? extends T> src) {
for (int i = 0; i < src.size(); i++)
dest.set(i, src.get(i));
}
}
另请参阅如何添加到列表
问题内容: 我无法理解以下文本…这是否意味着空的构造函数?为什么拥有两个不同的版本很重要? https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-2.html 在Java虚拟机级别,每个构造函数(第2.12节)都作为具有特殊名称的实例初始化方法出现。该名称由编译器提供。因为该名称不是有效的标识符,所以不能直接用Java编程语言编写的程序中使
我正在浏览微软的Rust教程,它是关于 实现函数,以便返回对插入向量中的值的引用 这里给出了解决方案,但它与我的不同之处在于它使用了 除了返回类型之外,我的和标准解决方案之间的另一个区别是,我只是简单地返回了参数,而标准解决方案使用复杂方式)。 我想知道我的解决方案是否有任何问题,本教程采取了另一种方式? 虽然@Masklin为我的问题提供了一个很好的答案,但它有点特定于我给出的示例,但没有直接解
我正在制作一个程序,并使用用户输入。当我得到一个字符串时,我总是使用. nextLine(),但我也使用了. Next(),它做同样的事情。有什么区别呢? 有什么区别?
createOrReplace eTempView和as函数别名火花sql查询使用的区别是什么? 我试图理解这两种方法之间的区别。
问题内容: 您能帮忙解释一下什么是带阴影的罐子,有用吗?还有什么是超级罐子。 问题答案: 我将首先解释什么是超级JAR,因为这将支持阴影说明。 超级JAR是包含多个JAR(或更常见的是,其他多个JAR本身)的内容的JAR。 您的应用程序几乎肯定会使用其他软件包,并且这些软件包可能以JAR的形式提供。使用Maven时,这些依赖关系表示如下: 在运行时,您的应用程序将期望在其类路径中找到此JAR中包含
在Java 7之前,JVM内存中有一个名为PermGen的区域,JVM以前在这里保存它的类。在Java 8中,它被移除并被称为元空间的区域所取代。 PermGen和Metaspace之间最重要的区别是什么? 我知道的唯一区别是,并且忽略了VM参数。