Q:什么是泛型。
A:又称为参数化类型,是含有单个或多个类型参数的类或接口的定义。
LinkedList是通用链表,内部类型是Object,可以存储任何对象,p245,泛型就相当于在LinkedList的基础上,限定了其可以存储对象的类型。
Q:如何定义泛型。
Q:如何指定泛型中的类型参数。
Q:什么是参数类型限制,以及如何应用。
Q:什么是通配符类型的规范,以及如何应用。
Q:如何定义通配符的限制。
Q:如何定义和使用参数化方法。
13.1
泛型,又称为参数化类型,是含有单个或多个类型参数的类或接口的定义。
为什么要有泛型?与类型安全有关。
因为LinkedList对象中可以加入不同的对象。
13.2
public class LinkedList<T> {
}
泛型的类型参数只能是类或接口,不可以使用基本数据类型。
13.2.2 泛型的实例化
LinkedList<String> strings = new LinkedList<String>();
LinkedList<LinkedList<String>> texts = new LinkedList<LinkedList<String>>();
13.2.3 泛型实例的运行时类型
LinkedList<Double> numbers = new LinkedList<Double>();
LinkedList<String> proverbs = new LinkedList<String>();
因为只有一个泛型,所以在运行时两个类将共享相同的Class对象,即泛型对应的Class对象,于是类名将是完全相同的。
numbers.getClass().equals(proverbs.getClass()); 为true
13.2.5 多重类型参数
Pair<String,String> entry = new Pair<String,String>("Fred Thrump","212 222 3333");
13.2.6 类型参数的作用域,是泛型类型的全部定义,但要排除类中的静态成员和初始化器。
这意味着不能用泛型的类型变量描述其中静态成员域的类型。
类似的,静态方法中返回值和参数类型不能是类型参数对应的类型变量。
13.2.7 泛型中的静态成员域
尽管由泛型生成的新类型共享相同的运行时类型,但它们仍然拥有独立的静态成员域。
13.2.8 类型参数限制
class LinkedList<T extends Serializable> implements Serializable{}
class MyType<T extends FancyClass & Serializable & MyInterface){}
所有的MyType<T>的参数化类型T的实参必须扩展类FancyClass,并且实现接口Serializable和MyInterface。
13.3 泛型和泛型接口
13.3.1 利用collection-based for 循环
若要使容器类的对象利用collection-based for 循环,必须且只需满足一个条件:它必须实现定义在包java.lang中的泛型接口Iterable<>。
接口Iterable<>是仅定义了方法iterator()的泛型,方法返回泛型接口Iterator<>的引用。
我们只要将类声明为实现接口Iterable<>,并实现方法iterator().
public class LinkedList<T> implements Iterable<T>{
public Iterator<T> iterator(){
}
}
接口Iterator<>声明的方法:
T next()
boolean hasNext()
void remove()
从链表中获取元素的工作机制如下:
LinkedList<String> strings = new LinkedList<String>();
...
Iterator<String> iter = strings.iterator();
String str = null;
while(iter.hasNext()){
str = iter.next();
}
没有必要将循环放入try代码块中,因为方法next()抛出的异常继承自RuntimeException。
13.3.2 实现一个迭代器
定义内部类用于定义链表的迭代器对象。
13.3.3 参数化的二叉树
public class BinaryTree<T extends Comparable<T>>{
}
13.4 原生类型变量
LinkedList list = null;
13.5 用通配符作为类型实参