为什么使用泛型
一、背景假设
用一个 Object 数组实现一个 list 容器存在如下的问题
- 第一点就是无法限制存入的数据的类型,自然无法保证这个容器装的就是同种类型的元素
- 第二点就是取出容器里面的元素的时候无法确定元素的具体的类型只能认为是一个 Object 类型,丢失了原来的类型信息,即便我们知道元素的类型,还是需要进行强制转换
针对不同的类型建立不同的容器解决了上面的问题,但是需要很多类型的容器,代码的通用性不高
二、泛型解决方案
- 泛型的本质就是将数据类型参数化,使得编写的代码具有更好的通用性
- 用于容器的设计的话,既对存入的数据类型进行了一定的限制,取出元素也无需进行强制转换
- 上面的强制转换和类型的检查都是由编译器来实现的,而不是虚拟机
泛型相关的转型问题:编译器为了避免容器元素的类型转换异常,根本就不允许把
ArrayList<Integer>
转型为ArrayList<Number>
,ArrayList<Integer>
和ArrayList<Number>
两者完全没有继承关系
泛型实现
一、泛型接口
public interface Comparable<T> {
/**
* 返回-1: 当前实例比参数o小
* 返回0: 当前实例与参数o相等
* 返回1: 当前实例比参数o大
*/
int compareTo(T o);
}
class Person implements Comparable<Person> {
String name;
int score;
Person(String name, int score) {
this.name = name;
this.score = score;
}
public int compareTo(Person other) {
return this.name.compareTo(other.name);
}
public String toString() {
return this.name + "," + this.score;
}
}
public class Main {
public static void main(String[] args) {
Person[] ps = new Person[] {
new Person("Bob", 61),
new Person("Alice", 88),
new Person("Lily", 75),
};
Arrays.sort(ps);
System.out.println(Arrays.toString(ps));
}
}
-不指定泛型参数类型时,编译器会给出警告,且只能将
<T>
视为Object类型
二、泛型编写
1、泛型类
- 基本的原则就是将特定的类型用泛型进行替换
- 泛型类中 T 基本