【问题标题】:What is the difference between <E extends Number> and <Number>?<E extends Number> 和 <Number> 有什么区别?
【发布时间】:2011-02-15 17:59:14
【问题描述】:

这个方法声明有什么区别:

public static <E extends Number> List<E> process(List<E> nums){

 public static List<Number> process(List<Number> nums){

你会在哪里使用前者?

【问题讨论】:

    标签: java generics


    【解决方案1】:

    第一个允许List&lt;Integer&gt;List&lt;Double&gt; 等的process。第二个不允许。

    Java 中的泛型是不变的。它们不像数组那样是协变的。

    也就是说,在 Java 中,Double[]Number[] 的子类型,但 List&lt;Double&gt; 不是 List&lt;Number&gt; 的子类型。但是,List&lt;Double&gt;List&lt;? extends Number&gt;

    泛型保持不变是有充分理由的,但这也是为什么extendssuper 类型对于子类型化灵活性通常是必要的。

    另见

    【讨论】:

    • 我认为如果我们有这样的方法,也可以解释一下差异:&lt;E extends Number&gt; E process(E elt) vs Number process(Number elt)
    【解决方案2】:

    后一种方法没有&lt;E extends Number&gt;的那个)只接受一个完全类型为List&lt;Number&gt;的参数,并且它总是 返回List&lt;Number&gt;。例如,它将接受List&lt;Integer&gt;

    前一种方法with&lt;E extends Number&gt;)是一个generic method,意味着它可以接受不同类型的@987654329 @s 它会返回相同类型的List,只要Lists 是 something 的列表 扩展Number,例如List&lt;Integer&gt;.

    例子:

    import java.util.ArrayList;
    import java.util.List;
    
    public class ProcessGenerics {
    
        List<Number>  listNumber  = new ArrayList<Number>();
        List<Integer> listInteger = new ArrayList<Integer>();
        List<Double>  listDouble  = new ArrayList<Double>();
    
    
        public static
            List<Number> processWithoutExtends(List<Number> nums){ return nums; }
    
        List<Number>  resultN = processWithoutExtends(listNumber);  // OK
      //List<Integer> resultI = processWithoutExtends(listInteger); // compile-error - method not applicable
      //List<Double>  resultD = processWithoutExtends(listDouble);  // compile-error - method not applicable
    
    
        public static <E extends Number>
            List<E> processWithExtends(List<E> nums){ return nums; }
    
        List<Number>  resultN2 = processWithExtends(listNumber);  // OK
        List<Integer> resultI2 = processWithExtends(listInteger); // OK
        List<Double>  resultD2 = processWithExtends(listDouble);  // OK
    
    }
    

    请参阅 Java 教程中泛型课程的通配符章节中的类似解释:
    http://java.sun.com/docs/books/tutorial/java/generics/subtyping.html

    另见 How to cast a list of inheriting objects to a collection of objects in Java? 这两个问题实际上都是关于泛型和子类型的,例如List&lt;Integer&gt; 是否是 List&lt;Number&gt; 的子类型(不是!!!)。

    【讨论】:

      猜你喜欢
      • 2011-01-23
      • 2012-08-12
      • 2018-06-03
      • 2012-09-23
      • 2013-08-13
      • 1970-01-01
      • 2017-04-21
      • 2016-03-24
      • 2016-03-23
      相关资源
      最近更新 更多