为了账号安全,请及时绑定邮箱和手机立即绑定

KTV和泛型(3)

标签:
Java

泛型除了KTV还有一个让人比较疑惑的玩意而且它就是用来表达疑惑的:?

虽然通过泛型已经达到我们想要的效果了例如

List<String> list = new ArrayList<String>();

这样就可以放心地存取String类型的数据

但是抱歉凡事总有个但是),应用的场景总是在不断增加的某一天

老板咱们之前给客户开发的功能中有个地方要改一改

神牛哪里要改呢

老板以前你写的代码List<Cat> list = new ArrayList<Cat>();只能列出Java宠物店托管的猫咪但是现在Java宠物店已经扩大了经营范围希望列出他们保管所有的宠物只要是宠物就行......

神牛这个easy

老板真的吗

于是神牛一通操作代码就改成了这样

class Cat extends Pets {};
class Dog extends Pets {};
public static void main(String[] args) {
    List<? extends Pets> list = new ArrayList<Pets>();
Pets pets = list.get(0);
Cat cat = (Cat)list.get(1);
Dog dog = (Dog)list.get(2);
}

 

然鹅过了一段时间Java宠物店由于经营不善已经将之前的宠物转卖送人了一部分现在就剩一些猫科动物所以现在的宠物笼子需要重新分配只要是猫科动物就要往里放以前写的代码

List<? extends Pets> list = new ArrayList<Pets>();

就满足不了给宠物分配笼子的需求了先想一想为啥不行了?)

神牛继续把键盘一顿猛敲代码又改成了这样

class Felidae {};
class Cat extends Felidae {};
public static void main(String[] args) {
    List<? super Felidae> list = new ArrayList<Felidae>();
    Cat cat = new Cat();
    list.add(cat);
}


这样一改以前的功能又不能用了为啥不能列出保管的宠物了?)

 

从以上需求场景可以看到

1、对于不确定或者不关心实际要操作的类型,可以使用无界通配符(尖括号里一个问号,即 <?>),表示可以持有任何类型;

2、<? extends T>称之为上界通配符」,表示只允许T及T的子类调用,例如只允许宠物类Pets的子类Cat和Dog调用

3、<? super T>刚好相反称之为下界通配符」,表示只允许T及T的父类调用,例如只允许Cat的父类Felidae调用

4、由于上界通配符<? extends T>中只知道T这个父类而不知道具体的子类所以用代替),因此它无法实现向列表中加入新元素的功能也就是做不到list.add()(这就是为什么满足不了给宠物分配笼子的需求);

5而由于下界通配符<? super T>中只知道T这个子类而不知道具体的父类所以用代替),因此它无法实现从列表中获取元素的功能也就是做不到list.get()(这也是为什么满足不了列出保管的宠物

 

刚才说了那么多稍稍有点绕总结一下

由于<? extends T>的只能取,不能存<? super T>得只能存,不能取因此在架构设计中就有一个推荐的实践经验

1、生产者producer一般<? extends T>

2、消费者consumer一般<? super T>

 

泛型讲到这里如果能够全部明白就可以真正畅快地去KTV嗨了而泛型其他的知识点像什么无界通配符泛型参数一致性多重限定基类劫持接口自限定类型循环泛型等乱七八糟的可以统统不去管了因为很多工程师一辈子的职业生涯中几乎都碰不到它们除非点背到极点还是最开始的那几个建议

1、不钻牛角尖,有问题见招拆招

2、解决主要宏观上、业务上的问题,暂时忽略次要的技术上的、细节上的问题

3、抓大放小,用好80/20原则



点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消