当前位置: 首页 > 知识库问答 >
问题:

两者之间的区别是什么?超级T>和[重复]

松和泰
2023-03-14

List之间有什么区别

我以前用List


共有3个答案

束建章
2023-03-14

我喜欢@Bert F给出的答案,但我的大脑就是这么看的。

我手里有个X如果我想把我的X写成一个列表,那个列表需要是一个列表,或者是一个列表,当我写它们的时候,我的X可以上升到列表,也就是说,任何一个超类...

List<? super   X>

如果我得到一个列表,我想从列表中读出一个X,那最好是一个X的列表,或者一个在我读出时可以向上转换为X的东西的列表,即任何扩展X的东西

List<? extends X>

希望这有帮助。

阙阳夏
2023-03-14

想象一下有这样的等级制度

通过写作

    List<? extends C2> list;

您的意思是,list将能够引用类型为(例如)ArrayList的对象,其泛型是C2的7个子类型之一(C2包括在内):

  1. 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个(红色)集合

如你所见,这里我们有七种常见的保险类型:C2D1D2E1E2E3E4

  • 你可以列表。添加(新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{}

萧嘉禧
2023-03-14

列表的通配符声明

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的任何列表都包含一个NumberNumber的子类。
  • 你不能读取整数,因为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值(你想在列表中写入Ts),你需要用声明它?超级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参数。