第12章 泛型程序设计

12.1使用泛型程序设计的原因?

    1)得程序具有更好的可读性和安全性。

    2)在没有泛型之前采用继承实现,用Object存储,使用时采用强制转换。

12.2定义简单的泛型类

    1)泛型类可以有多个类型变量<多个>

    2)类型变量使用大写形式,且比较短,这是很常见的。在Java库中,使用变量E表示集合的元素类型,K和V分别表示表的关键字与值的类型。T(需要时还可以用临近的字母U和S)表示"任意类型"。

12.3泛型方法

    1)类型变量放在修饰符的后面,返回类型的前面。

    2)调用方式对象.<>方法名

12.4类型变量的限定

    1)限定T必须实现Comparable接口<T extends Comparable>,限定类也使用extends关键字

    2)一个类型变量或通配符可以有多个限定,限定类型用"&"分隔,<T extends Comparable & Serializable>

    3)有多个限定时,类必须是第一个,且不能有多个类,接口在后<T extends ArrayList & Comparable>

12.5泛型代码和虚拟机。

1)虚拟机中没有泛型,只有普通类和方法。

2)所有的类型参数都用它们的限定类型替换;类型参数用第一个限定类型变量来替换,如果没有给定限定就用Object替换。

3)为了提高效率,应该将标签(tagging)接口(即没有方法的接口)放在边界列表的末尾。

4)桥方法被合成来保持多态(当一个类集成自泛型类,重写方法时,编译器会自动生成桥方法来保持多态)。

5)设计Java泛型类型时,主要目标是允许泛型代码和遗留代码之间能够互操作,因为实现某些类时,Java中还不存在泛型。

12.6约束与局限性

1)大多数限制都是由类型擦除引起的。

2)不能使用基本类型实例化类型参数,因为Object不能存储基本数据类型。

3)运行时类型查询只适用于原始类型(a instanceof Pair<String> //Error)。

4)不能创建参数化类型的数组。

5)不能实例化类型变量。

6)泛型类的静态上下文中类型变量无效。

7)不能抛出或捕获泛型类的实例,不过在异常规范中使用类型变量是允许的(throw T,throws T)。

8)注意擦出后的冲突。

12.7泛型类型的继承规则

    Student->Person,ArrayList<Student>不继承于List<Person>。

12.8通配符类型

1)通配符的子类限定<? extends Employe>,通配符的超类限定<? super Manager>;直观的讲,带有超类限定的通配符可以向泛型对象写入,带有子类型限定的通配符可以从泛型对象读取,原因当然是间接的多态问题了。

2)无限定的通配符<?>,它与原始类型最大的区别在于是否可以用任意Object对象调用原始类的setObject方法(有时一些简单的操作可以避免<T>等的声明,且<?>不可写)。

3)通配符的捕获,需要写一个辅助泛型方法<T>,在使用通配符的方法中调用即可,但是编译器必须确信通配符的表达的是单个、确定的类型。例如,ArrayList<Pair<T>>中的T永远不能捕获ArrayList<Pair<?>>中的通配符。

12.9 反射和泛型

    Class类是泛型的,例如String.class实际上是一个Class<String>类的对象;类型参数十分有用,这是因为它允许Class<T>方法的返回类型更加具有针对性(不需要强制类型转换)。

 

 

 

 

posted @ 2017-10-24 16:50  Bug的梦魇  阅读(171)  评论(0编辑  收藏  举报