关于泛型我有些不懂,帮我看看啊
public static <E extends Number> List<? super E> process(List<E> nums) //这是一个方法头
我有三个地方不明白:
1.<E extends Number> 要求E应该是Number的子类或是Number类,<? super E>要求是E或E的父类,到底应该遵循哪一个?我觉得它们应该一致才可以呢?
2.上述方法的返回类型要求是List 为什么返回ArrayList就不可以呢?
     比如ArrayList<Integer> input=null;
       ArrayList<Integer> output=null;
       output=process(input);//出错了 要求返回类型为List.可是ArrayList是List的实现类啊?为什么不可以呢?
3. <E extends Number>与<? extends Number>有什么不同啊?

解决方案 »

  1.   

    1、遵循<E extends Number>。由于java.util.List也是泛型类,List<T>,因此
    在使用时必须填上具体的类型,那么这里使用通配符表示它可以接受在调用process方法时所传入的泛型参数为E或E的父类(Number)。因此在调用process方法时真正的泛型参数是E,它的约束是必须是Number的子类或Number类。2、因为返回类型是List<? super E>,你返回ArrayList<Integer>当然不行。因为ArrayList是List的具体实现类,List是接口,而接口类无法转为自己的实现类;父类不能隐式地转为子类一样。3、
      

  2.   

    1:
    遵循2个都可以.
    2,3:
    List与 ArrayList的继承关系(ArrayList继承List) 
    然后再根据方法定义的泛性方法结构来判断,List<? super E>这个的意思是函数的换回类型必须是符合List<E>,而前面的<E extends Number>有又给E做了定义,那就是E必须是 
    Number或者是它的子类,同样List<E> nums这个的意思是nums必须是List<E>或者List<E>的子类. 
      

  3.   

    public static  <E extends Number> List <? super E> process(List <E> nums)
    ------
    解释如下:
    1、<E extends Number> 是个限定,是说在这个方法内出现的E类型,必须extends Number。
    2、List <? super E>,这里的<? super E>是修饰List的,即申明返回值是个List,
       其元素为E的super类型。
    3、List <E>,这里是说此方法的参数是个List,并且元素类型为E,因为有1的限定,也就是说
       这个E必须是extends Number。
      

  4.   


    第一:指明process方法的参数是List <E>类型的,List里必须是E这个元素,List <? super E>指明返回类型List的元素必须得是E的父类,或者是其本身类型,<E extends Number>指明,对这个元素E的约束,指明这个元素E必须得是NUMBER的本身或者其子类~第二:这是显然得不行,就是向下转型!
    第三:<E extends Number>与 <? extends Number>
    <E extends Number>是指明E必须得是继承Number或者其本身,<? extends Number>而这个不是对元素E的约束,而是对这个泛型的约束,任何一个继承Number或者其本身!
      

  5.   

    我上次第三点来不及回答,因为我们这快要断网了。3、<E extends Number>中的E是泛型形参,用来声明我定义的类或方法将采用以E为类型的泛型。比如:public static  <E extends Number> void Hello(E i) { }
    而后面的<? super Number>或<? extends Number>中的?表示通配符,用于泛型实参传递。而Number是对通配符?的限定,也就是对调用process方法时,传入泛型实参类型的限定。比如:
    public static  <E extends Number> List<? extends Number> Hello() {
        return new ArrayList<E>();假设process()方法在MyClass类中。
    像上面的代码,如果这么调用:MyClass.<Integer>Hello();就没有问题,因为实参Integer继承了Number。
    而如果是这么调用:MyClass.<String>Hello();那么就会出错。因为String与Number没有继承关系。
    这是对<E extends Number>的讨论。
    如果上面代码最后返回return new ArrayList<String>();那么就会出错,因为返回类型为List<? extends E>,所以ArrayList<>中的泛型参数类型必须是Number的子类或Number。所以new ArrayList<E>()没有问题,因为E已经被声明为Number的子类或Number。
    前者是在方法调用时判定,后者是在方法体内进行判定。