为什么使用泛型
在定义类,接口和方法时,泛型能将类型(类和接口)座位参数使用。
泛型相比非泛型的优点
- 编译时更强的类型检查
- Java编译器对泛型代码使用强类型检查,如果代码违反了类型安全则显示错误
- 消除强类型转换
// 需要类型转换
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);
// 不需要强制类型转换
List<String> list = new ArrayList<String>();
list.add("hello");
String s = list.get(0);
复制代码
- 程序员可以实现泛型算法
- 使用泛型实现泛型算法,作用在不同类型的集合上,可以定制,类型安全且易读
示例Box类
public class Box {
private Object object;
public void set(Object object) {
this.object = object;
}
public Object get() {
return object;
}
}
复制代码
以上Box类的方法可以接收或返回一个对象(Object),所以只要所用的不是几倍类型的数据,用户就可以随意传递。 编译时,我们无法验证该类是如何使用的,而当代码执行到某处时,可能把一个整型数放到了Box中,并期望从Box中获取整型数,然而代码执行到另一处时可能错误的传递了字符串,从而导致运行时错误。
Box类的泛型版本
一个泛型类的定义格式如下
class name<T1, T2 , ..., Tn>{/* ... */}
复制代码
类名后面用“<>”标示出来的是类型形式参数部分,指明类型形式参数是T1,T2,...,Tn
public class Box<T> {
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
}
复制代码
泛型类型调用和实例化示例
Box<Integer> integerBox;
Box<Integer> integerBox = new Box<Integer>();
复制代码
多个类型参数
public interface Pair<K, V> {
public K getKey();
public V getValue();
}
public class OrderedPair<K, V> implements Pair<K, V> {
private K key;
private V value;
public OrderedPair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
// 创建实例
Pair<String, Integer> p1 = new OrderedPair<String, Integer>("Even", 8);
// Java 编译器可以从声明OrderedPair<String, Integer>中推断出K,V的类型,所以可以写为
Pair<String, Integer> p1 = new OrderedPair<>("Even", 8);
复制代码
参数化类型
Pair<String, Box<Integer>> p = new OrderedPair<>("Even", new Box<Integer>(...));
复制代码
《Java语言导学》