【问题标题】:Arraylist generics/wildcard etiquetteArraylist 泛型/通配符礼仪
【发布时间】:2017-03-21 18:31:11
【问题描述】:

我希望了解其中每一个的所有详细原因/动机/用途,但是有很多组合,而在我看来都是一样的,我对我认为的细微差别感到困惑称为泛型(通配符、对象、T、E 等,不知道 所有 是否属于泛型)

如果我有这样的东西,我想制作一个数组列表:

Media<T> //Baseclass
Book<T> //Subclass
Movie<T> //Subclass

在这种情况下,哪些最适合制作/使用,为什么?(如有必要,假设我将只对这些书籍、电影使用字符串和整数):

  • ArrayList&lt;Media&gt; = new ArrayList&lt;Media&gt;;
  • ArrayList&lt;Media&lt;T&gt;&gt; = new ArrayList&lt;Media&lt;T&gt;&gt;;
  • ArrayList&lt;Media&lt;?&gt;&gt; = new ArrayList&lt;Media&lt;?&gt;&gt;;
  • ArrayList&lt;? extends Media&gt; = new ArrayList&lt;? extends Media&gt;;
  • ArrayList&lt;Object&gt; = new ArrayList&lt;Object&gt;;
  • ArrayList&lt;&gt; = new ArrayList&lt;&gt;;
  • 其他的?

如果基类是抽象的,那会有所不同/影响选择吗?

我知道 Object 是超超类并且“可以采用任何形式”,我知道通配符表示下一个对象可能是任何类型,但 E 和 T 也是如此,对吗?我知道 ?扩展媒体意味着它将是一种媒体。在我看来一切都一样,否则我不知道如何证明一个特定的选择。

编辑: 下面的完整示例

import java.awt.*;
import java.util.ArrayList;

public class Something {

    public class Media<T>{
        T data;
        public T getData(){ return this.data; }
        public void setData(T data){ this.data = data; }
    }
    public class Book<T> extends Media<T>{
        T data;
        @Override
        public T getData(){ return this.data; }
        @Override
        public void setData(T data){ this.data = data; }
    }
    public class Movie<T> extends Media<T>{
        T data;
        @Override
        public T getData(){ return this.data; }
        @Override
        public void setData(T data){ this.data = data; }
    }

    ArrayList<Media> arrList;

    public Something() {
         this.arrList = new ArrayList<Media>();
         this.arrList.add(new Book<Integer>());
         this.arrList.add(new Movie<String>());

         this.arrList.get(0).setData(12);
         this.arrList.get(1).setData("Hello");

         System.out.println(this.arrList.get(0).getData()+10);
         System.out.println(this.arrList.get(1).getData()+10);
    }

    public static void main(String[] args) {
        Something s = new Something();
    }

}

【问题讨论】:

  • ArrayList&lt;Media&lt;T&gt;&gt; 似乎是最自然的选择。但尚不清楚T 是什么或您的实际用例是什么。
  • 只是将各种类型添加到基类数组中,如下所示:arrList.add(new Book&lt;String&gt;); arrList.add(new Movie&lt;Integer&gt;); 可能还有一些来自基类的函数,每个函数都覆盖了返回类型 T。
  • 如果您发布一个更完整的示例会有所帮助。
  • 刚刚添加了一个。
  • Book 是什么意思? Movie 是什么意思?在我看来,您的示例根本不需要

标签: java generics arraylist


【解决方案1】:

这不是一个完整的答案,但请参阅this question 了解在泛型类型规范中使用“super”或“extends”的效果。简短的版本是 Collection&lt;? extends T&gt; 是只读的,而 Collection&lt;? super T&gt; 是仅附加的。

出于这个原因,我个人更喜欢完全避免这两个限定词,因为它们通常比简单的 Collection&lt;T&gt; 更具限制性。

但是,在设计用于反差和反差的 API 时,它们有时很有用(请参阅 this question

Collection&lt;?&gt; 我只在处理遗留代码(不使用泛型)时使用以避免编译器警告。它实际上与Collection&lt;Object&gt; 相同,但对我来说更清楚。我尽量不写需要&lt;?&gt;的新代码

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-20
    • 2011-11-12
    • 1970-01-01
    • 1970-01-01
    • 2017-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多