Java编程思想笔记(十五)——泛型

感悟

首先这一章内容很多,可以说是目前以来最大的章节了,非常全面的介绍了泛型,还可见泛型的重要程度和应用广泛。本章后半篇幅难度有点大,探讨了各种泛型的前因后果,以及Java泛型的缺陷,可以慢慢理解。泛型使Java抽象更进一步,是Java SE5的重大变化之一。之后章节会经常接触泛型,掌握几种常见泛型例子是本章的重点。

笔记
  • 15.1 与C++的比较
加深理解用,个人觉得不了解C++不必强求
  • 15.2 简单泛型
    1)一个元祖类库
    2)一个堆栈类
    3)RandomList
1、由容器类引入,持有对象说起泛型的作用
2、元组:一组对象打包存储于其中一个单一对象
3、用堆栈和随机选取元素示例了泛型通用性
  • 15.3 泛型接口
1、将泛型应用于接口,同时结合生成器generator和工厂方法设计模式例子进行说明。
2、例子中实现了Iterable<T>,然后用到了前面章节的循环遍历、内部类、和泛型结合,可以说是集大成者。
3、Fibonacci数列的第一个例子,将递归思想、生成器、和泛型结合,可见作者功底深厚。
4、Fibonacci数列第二个例子,更是将前面的所有特性Iterable接口,匿名内部类,泛型,再集成适配器模式进行示例。不佩服作者都不行。
  • 15.4 泛型方法
    1)杠杆利用类型参数推断
    2)可变参数与泛型方法
    3)用于Generator的泛型方法
    4)一个通用的Generator
    5)简化元祖的使用
    6)一个Set实用工具
1、尽量使用泛型方法,static方法要使用泛型,必须称为泛型方法
2、public <T> void f(T x){System.out.println(x.getClass().getName())},泛型方法不必指明参数类型,编译器会自动匹配(类型参数推断)
3、类型参数推断(简化类型说明语句,传参需额外说明,了解就好)
4、结合泛型方法,生成器Generator透明地进行容器数据生成,进而示例了通用BasicGenerator,因为类型推断,大大减少了编写代码
5、重载简化创建元祖代码
6、泛型方法结合Set、Enum进行示例并集、交集、差集使代码方便快捷
  • 15.5 匿名内部类
把匿名内部类和泛型结合在一起,实现Generator接口,更加简洁直观
  • 15.6 构建复杂模型
把元祖和泛型结合在一起,构建复杂数据模型
  • 15.7 擦除的神秘之处
    1)C++的方式
    2)迁移兼容性
    3)擦除的问题
    4)边界处的动作
1、理解擦除,List<String>和List<Integer>是相同类型
2、理解边界,重用关键字extends
3、从非泛化代码到泛化代码的转变过程
  • 15.8 擦除的补偿
    1)创建类型实例
    2)泛型数组
1、运行时需要知道确切类型信息的操作将无法操作,比如 T var = new T();通过引入类型标签来对擦除进行补偿,传入Class对象。
2、泛型也可以结合工厂方法,传入Class对象用newInstance()方法或显式创建工厂对象来进行创建对象,前者需要Class类有默认构造器。
3、使用ArrayList创建泛型数组或者创建对象数组然后将其转型: private T[] array; array = (T[])new Object[sz];
4、底层数组内部是Object[],所以期望是通过传入一个类型标记Class<T>,对擦除进行补偿,以便知道运行时的确切类型。
5、Java SE5标准类库中源代码存在参数化类型的转型,这种做法是懒散的,不应该遵循这种做法。
  • 15.9 边界
1、可以按照自己的边界类型来调用方法,重用了extends关键字,多重边界原则上是先类再接口,但只能是一个类多个接口。
2、通过继承可以消除边界冗余,每个层次上都添加了边界,因而不必在每个类中重复。
  • 15.10 通配符
    1) 编译器有多聪明
    2)逆变
    3)无界通配符
    4) 捕获转换
1、从类数组入手,引出导出类型的数组问题,可以编译,但是运行报错还有List数组泛型不支持导出类型泛型。
2、引出List<? extends Fruit>和超类型通配符List<? super T>,解决了泛型数组的限制折中方案,加深了协变和通配符的理解,这里要理解一点就是 extends是用来拿,super是用来放。
可以参考这篇文章https://www.cnblogs.com/drizzlewithwind/p/6100164.html
简单说就是下界extends取出来超出不了,上界super放进去超出不了。
3、介绍无界通配符<?>与原生类型的区别。
4、捕获转换了解就好,即方法内部捕获后可以回转调用另一个使用这个确切类型的方法。
  • 15.11 问题
    1) 任何基本类型都不能作为类型参数
    2) 实现参数化接口
    3) 转型和警告
    4) 重载
    5) 基类劫持了接口
1、基本类型不能作为类型参数,解决方案是使用包装器类,但有一些限制。
2、一个类不能实现同一个泛型接口的两种变体
3、有时泛型没有消除对转型的需要,编译器产生警告是不恰当的。
4、由于擦除,无法重载方法中相同类型泛型
5、基类确定了类型参数,其他实现类不能与基类型参数之外的任何对象比较。
  • 15.12 自限定的类型
    1) 古怪的循环泛型
    2) 自限定
    3) 参数协变
1、简单入手:示例了一个新类,继承自一个泛型类型,这个泛型类型接受我的类的名字作为参数。
2、自限定强制泛型当作其自己的边界参数来使用,这样这个类所用的类型参数将与使用这个参数的类具有相同的基类型。简单说就是限定了自己的导出类
3、自限定类型价值在于产生协变参数类型,使继承的方法只能获得某个方法的一个版本,接受确切的参数类型,重写而不是重载。
  • 15.13 动态类型安全
旧时代吗可能会破坏容器,例如向原生List传递泛型容器List<Class>,Java SE5添加了一组方法,受检查的容器会在插入不正确对象时抛出异常
  • 15.14 异常
1、因为擦除,将泛型用于异常非常受限,不能捕获泛型类型异常。
2、类型参数可以用在throws子句中,可以编写随检查异常类型而发生变化的泛型代码
  • 15.15 混型
    1) C++中的混型
    2) 与接口混合
    3) 使用装饰器模式
    4) 与动态代理混合
1、引出混型概念,Java中使用接口来产生混型效果
2、使用装饰器模式进一步介绍混型,与混型进行对比
3、结合动态代理演示了混型,但仍需向下转型
  • 15.16 潜在类型机制
1、引出潜在类型机制,即横跨类继承结构,调用不属于某个公共接口的方法,只要有那个方法即可
2、Java对潜在类型存在缺陷,被强制要求使用一个类或接口
  • 15.17 对缺乏潜在类型机制的补偿
    1) 反射
    2) 将一个方法应用于序列
    3) 当你并未碰巧拥有正确的接口时
    4) 用适配器仿真潜在类型机制
1、额外的努力实现潜在类型机制,比如反射
2、结合序列和反射优雅实现潜在类型机制
3、结合适配器和泛型实现潜在类型机制,使得真正泛化的潜在类型机制更进一步
  • 15.18 将函数对象用作策略
结合策略模式将变化的事物隔离到一个函数中,和泛型一起实现潜在类型机制
  • 15.19 总结:转型真的如此之槽吗?
Java泛型是后来加入的,编写更泛化的代码,需要额外努力,比如结合理解适配器设计模式的概念和实现,虽然带来了一些难度,但也会加入附加价值。只有时间将会说明Java的泛型方法对这种语言造成的最终影响。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值