java 泛型 extends 和 super快速记忆。

来源:互联网 发布:淘宝卖家星级怎么升级 编辑:程序博客网 时间:2024/05/11 11:45

java 泛型 extends 和 super快速记忆。
为了方便总结的更全面一点,Demo如下:

public class A {}public class B extends A {}public class C extends B {}这里全部以B为临街,看看上下界到底是什么情况

第一种情况,不带任何通配符,extends 和 super

 ArrayList<B> Blist = new ArrayList<>();A a = Blist.get(0);//(1)正确B b = Blist.get(1);//(2)正确C c = Blist.get(2);//(3)错误Blist.add(new A());//(4)错误Blist.add(new B());//(5)正确Blist.add(new C());//(6)正确

结果我们也可以预料到:
B是已经确定的类型,ArrayList里面相当于有一个动态数组object[]来存储我们add()进去的数组。根据java多肽的性质,父=子才是正确的,而子=父是错误的。所以B和B的父类都可以正确接受Blist.get()得到的值,因为返回的值一定是B类型,B可以接受get()的值,那么B的父类一定也可以。同理,Blist.add()的值必须是B和B的子类,这样父=子才可以成功。

再来看看上届extends B的情况

ArrayList<? extends B> extendsList = new ArrayList<>();a = extendsList.get(0);//正确b = extendsList.get(1);//正确c = extendsList.get(2);//错误extendsList.add(new A());//错误extendsList.add(new B());//错误extendsList.add(new C());//错误

因为 ? extends B,所以extendsList里面存储的是B和B的子类,所以extendsList.get()的值可以赋值给B,同理,可以赋值给B,当然可以赋值给B的父类,但是C就不行,因为C c=new B()不成立。那么为什么add的值不行呢?因为不确定,虽然保证了add()的值一定是B的子类,但是,可以为C,也可以为D(假设D也继承了B),所以所有add()全部失败。。。(姑且这么记吧)

然后是下界super B

ArrayList<? super B> superList = new ArrayList<>();a = superList.get(0);//错误b = superList.get(0);//错误c = superList.get(0);//错误superList.add(new A());//错误superList.add(new B());//正确superList.add(new C());//正确

? super B,所以里面存储的是B和B的父类,既然是父类,那所有superList.get()就不成立了,因为B的父类是不确定的,可能是A,也可能是X(假设X是B的父类或者A的父类)。但是,下界是确定的,add()的值,必须为B或者B的子类,这样才符合java多态,而add(new A())显然就不行。
所以,我们想只读(只是想得到)某个T及T的子类,可以采用< ? extends T >的方式,如果想加入T及T的子类,采用< ? super T >的方式

原创粉丝点击