zoukankan      html  css  js  c++  java
  • 泛型 ? extends(super) E

    ? extends E 和 ? super E

    B类:
    public class B implements C {
    @Override
    public Map convert(Object from) {
       return null;
    }

    }

    C类:
    @FunctionalInterface
    public interface C<F, T, D> {

       Map<String, Integer> convert(T from);

    }

    W类:
    public class W extends V {

    }


    V类:
    public class V implements D {

    public void f() {
    }
    }

    D接口:(实现了接口的实现类可以调用该接口的方法——> ? extends D 中的D可以是类,也可以是接口,不影响)
    public interface D {

    }


    Z类:
    public class Z extends W {

    }

    A类:
    public class A {
       public void f() {

            B b = new B();

            C c = new B();

            V v = new V();

            D d = new D();

            W w = new W();

            Z z = new Z();

            Map<String, ? extends C> map = new HashMap<>();
            map.put("", b);  //编译不通过! ->因为不知道具体的实现类

            Map<String, ? super C> map2 = new HashMap<>();
            map2.put("", b);     //编译通过! ->因为限定put()的下限是C ,而B类实现了C接口;

            Map<String, ? super V> map3 = new HashMap<>();
            map3.put("", d);  //编译不通过! ->因为d不是V的子类

            Map<String, ? super V> map4 = new HashMap<>();
            map3.put("", w);    //编译通过! ->因为w是V的子类
            map3.put("", v);    //编译通过! ->添加的是V自身
            map3.put("", z);    //编译通过! ->因为z是W的子类,也算是V的子类
       }
    }

    总结:


      !!!这里的 E 理解为一个范围,而不单单指一个类,范围是(从父类到其子类 这些类)。
     
      
    ? extends E:指的是E及其E的子类,指定了泛型的上限(E),由于E是该范围内最上面的类,所以在list.add(具体类)是不可以的,因为只知道泛型的上限,但具体添加的对象和 list = new ArrayList<>(),中的类不一定匹配,会出现类型转换问题,所以干脆不可以添加。

    super E:指的是E及其E的父类,指定了泛型的下限(E),由于指定了泛型的下限E,所以添加的对象只能是E或者E的子类,这样就不会出现类型转换错误,这就可以添加了,编译成功。

    关键字:1.防止类型转换错误  

                   2.下限:相当于已经指定类型

    eg:

    用list解释,map同理


    目前有四个类,Person类、Student类、Teacher类、GoodStudent类。

    四个类之间的关系:
    Student类、Teacher类都继承了Person类
    GoodStudent类继承于Student类

    ? extends Person类 : 这时指定的上限是Person,在list.add()的时候,由于只知道上限是Person,不知道具体的 ( List<> list = new ArrayList<>(); ) list是什么类型,所以不可以添加,因为new ArrayList<> 的时候,<>泛型可能是Teacher,也可能是Student,所以此时不管list.add()的是什么,是编译不通过的。-->因为此时还没有指定具体的 ArrayList<>;

    ? super Student : 这时指定的下限是Student,在list.add()的时候,只能addStudent或者其子类,这是已经指定好的,所以此时,我们就可以add(Student/Student子类了)。

  • 相关阅读:
    [jdk] JDK1.5新特性
    [maven] maven介绍
    [Ant] bulid.xml配置详解
    [spring] spring面试题
    .net(C#)时间相减、C#计算时间间隔
    如何记录应用程序日志
    交换机、集线器、路由器区别和使用浅谈
    ASP.NET 在域控制器上使用默认 ASPNET 帐户不能正常运行
    .NET 4中Entity Framework简介
    WCF传输性能测试
  • 原文地址:https://www.cnblogs.com/tian666/p/7885496.html
Copyright © 2011-2022 走看看