Java核心技术第八章-泛型
2019-12-04 11:44
摘要#
本文根据《Java核心技术 卷一》一书的第八章总结而成,部分文章摘抄书内,作为个人笔记。
文章不会过于深入,望读者参考便好。
为什么要使用泛型程序设计#
泛型程序设计(Generic programming) 意味着编写的代码可以被很多不同类型的对象所重用。
类型参数的好处#
在没有泛型类之前,ArrayList类只维护一个Object引用的数组:
Copy
public class ArrayList {
private Object[] elementData; // 用于存放数据
public Object get(int i) { . . . }
public void add(Object o) { . . . }
...
}
问题
1.获取一个值时必须进行强制类型转换
2.这里没有错误检査。可以向数组列表中添加任何类的对象,如果数组的类型不一致,将 get 的结果进行强制强制类型,就会错误。
泛型提供了一个更好的解决方案: 类型参数:
Copy
ArrayList array = new ArrayList():
利用类型参数的信息,我们就可以在添加数据的时候保持类型统一,调用get方法时候也不需要进行强制类型转换,因为我们在初始化的时候就定义了类型,编译器识别返回值的类型就会帮我们转换该类型。
定义一个简单泛型类#
Copy
public class Pair {
private T num;
public Pair(T num) { this.num = num; }
public T getNum() { return num; }
public void setNum(T num) { this.num = num; }
}
我们可以看到,在Pair类名后面添加了一个,这个是泛型类的类型变量,而且还可以有多个类型变量,如
Copy
public class Pair {
...
}
如果我们实例化Pair类,例如:
Copy
new Pair;
那么我们就可以把上述的Pair类想象成如下:
Copy
public class Pair {
private String num;
public Pair(String num) { this.num = num; }
public String getNum() { return num; }
public void setNum(String num) { this.num = num; }
}
是不是很简单呢?在Java库中,使用变量E表示集合的元素类型,K和V分别表示表的关键字与值的类型,T、U、S表示任意类型。
泛型方法#
定义一个带有类型参数的方法
Copy
public static T getMiddle(T... a) {
return a[a.length / 2];
}
可以看到类型变量(< T >)放在修饰符( public static )的后面,返回类型(T)的前面。泛型方法可以定义在普通类或泛型类中。
类型变量的限定#
如果我们需要对类型变量加以约束,例如:传入的变量必须实现Comparable接口,因为需要该变量调用compareTo的方法。这样我们就可以使用extends关键字对变量进行限定。
Copy
public T max(T a) {
a.compareTo(...);
...
}
无论变量需要限定为继承某个类或者实现某个接口,都是使用extends关键字进行限定。
泛型代码和虚拟机#
类型擦除#
无论我们在代码中怎么定义一个泛型类、泛型方法,都提供了一个相应的原始类型。原始类型的名字就是删去类型参数后的泛型类姓名。如 的原始类型为 Object,的原始类型为MyClass。
代码就行下面这样:
Copy
public class Pair {
private T property;
public Pair(T property) {
this.property = property;
}
}
类型擦除后:
Copy
public class Pair