《Java 卷1 基础知识》
第8章 泛型程序设计
泛型程序设计意味着编写的代码可以被很多不同类型的对象所重用
实际上,在Java增加泛型类之前已经有一个ArrayList类,它可以聚集任何类型的对象
一个泛型类就是一个具有一个或者多个类型变量的类
类型变量用尖括号(<>)括起来,并放在类名的后面
用具体的类型变量就可以实例化泛型类型
从表面上看,泛型类类似于C++的模板类
在Java中,不但可以定义泛型类,还可以定义泛型方法,即一个带有类型参数的简单方法
在定义泛型方法时要注意类型变量放在修饰符的后面,返回类型的前面
如:public static <T> T getMiddle()
泛型方法可以定义在普通类中,也可以定义在泛型类中
而在调用泛型方法时,在方法名的尖括号中放入具体的类型即可
有时,类或方法需要对类型变量加以约束
例如,一个使用泛型方法实现的min方法,该min方法并不是对任何类型都可以获取其最小值,
要想使min方法能成功,就需要保证min方法的T实现了compareTo方法,即实现了Comparable接口
换句话来说,需要将T限制为实现了Comparable接口的类
通用记法:<T extends BoundingType>
在这里应为 <T extends Comparable>
虚拟机没有泛型类型对象——所有对象属于普通类
无论何时定义了一个泛型类型,都自动提供了一个相应的原始类型。
原始类型就是删去类型参数后的泛型类型名
擦除类型变量,并替换成限定类型(无限定的变量用Object)
约束与局限性
- 不能用基本类型实例化类型参数
- 运行时类型查询只适用于原始类型;
- 即试图查询一个对象是否属于某个泛型时,倘若使用instanceof会得到一个编译器错误,如果强制类型转换会得到一份警告
- 不能创建参数化类型的数组;但只是进行声明还是合法的
- Varargs警告
- 不能实例化类型变量
- 不能构造泛型数组
- 泛型类的静态上下文中类型变量无效;即不能在静态域或方法中引用类型变量
- 不能抛出或捕获泛型类的实例
- 可以消除对受查异常的检查
- 注意擦除后的冲突
- 泛型类型的继承规则
- 这里假设Employee是Manager的超类,Pair是一个泛型类型
- 那么Pair
不是Pair 的子类 - 当然,泛型类可以扩展或实现其他的泛型类,就这一点与普通类没有什么区别
在通配符类型中,允许类型参数变化
Pair<? extends Employee>
表示任何泛型,它的参数类型是Employee的子类,如Pair<Manager>
通配符的超类型限定:
Pair<? super Manager>
这个通配符限制为Manager的所有超类型
无限定的通配符:Pair<?>
第9章 集合
Java的集合类库将接口与实现分离
在Java类库中,集合类的基本接口是Collection接口
Collection接口有两个基本方法
public interface Collection
{
boolean add(Element);
Iteratoriterator();
...
}
add添加元素,如果添加后改变了集合就返回true;
iterator方法用于依次访问集合中的元素
迭代器Iterator接口包含4个方法
public interface Iterator
{
E next();
boolean hasNext();
void remove();
default void forEachRemaining(Consumer<? super E> action);
}
反复调用next方法,可以逐个访问集合中的每个元素
但是到了集合的末尾,next方法会抛出一个NoSuchElementException,因此需要调用hasNext方法
remove方法将会删除上次调用next方法返回的元素
如果调用remove之前没有调用next将是不合法的
集合框架中的接口:
集合中有两个基本接口:Collection和Map
而List是一种有序集合
Set接口等同于Collection接口,不过Set的add方法不允许增加重复的元素
SortedSet和SortedMap接口会提供用于排序的比较器对象。