目录
注:如有错误,欢迎指出~3Q~
概念
泛型:本质是参数化类型,Java SE1.5新增的特性。
特点
类型参数只能用来表示引用类型。对于基本数据类型,提供了自动装箱机制,从而可以使用对应的包装类型作为泛型化参数传入。泛型可以用在接口、方法和类上,分别称作泛型接口、泛型方法和泛型类。
优势
强化类型安全,因为泛型在编译期进行类型检查,减少了运行期类型转换异常,保证了类型安全。
一定程度上提高了代码复用。
类型的依赖关系更加明确了,增加了代码和文档的易读性。
使用
泛型特性-擦除
编写好的泛型代码,在编译成功之后,会采取去泛型化的措施。也就是说这段泛型代码,只在编译阶段有效,在运行阶段所有的泛型类型都将被擦除成基类型,即Object,因此在运行阶段参与运算的类型是Object。而相关的对象在进入和离开方法的边界处会添加相应的类型检查和类型转换的方法。
例如:
List<String> stringList = new ArrayList<>();
List<Integer> integerList = new ArrayList<>();
System.out.println(stringList.getClass()); // OutPut: class java.util.ArrayList
System.out.println(integerList.getClass()); // OutPut: class java.util.ArrayList
泛型标识符
T、E、V、K等
例如:
public class CarFactory<T> {
private Class clazz;
public CarFactory(Class clazz) {
this.clazz = clazz;
}
public T createInstance() throws Exception {
return (T) this.clazz.newInstance();
}
}
使用泛型的三种方式
泛型类
public class Test<T> {
private T object;
public void set(T object) {
this.object = object;
}
public T get() {
return this.object;
}
}
泛型接口
public interface Test<T> {
T next();
}
泛型方法
public <T> T getAddObject(T element, List<T> list) {
list.add(element);
return element;
}
其中<T>用来作为泛型方法的标示,放在返回值之前。如果要在类中使用静态方法,该静态方法需要使用泛型参数,那么需要在返回值前面加上泛型方法的声明标志<T>,标明这是一个泛型方法。
通配符
<?> : 泛型无限定通配符 标示不确定的类型
例如:
public void out(List<?> list) {
System.out.println(list.toString());
}
// 使用时,?表示可以使用任意一个类型,如下:
List<String> stringList = new ArrayList<>();
List<Integer> integerList = new ArrayList<>();
// 而当List的类型参数标明了确定的类型以后,如下:
public void out(List<String> list) {
System.out.println(list.toString());
}
List<String> stringList = new ArrayList<>();
List<Integer> integerList = new ArrayList<>(); // 报错
<? extends T> : 泛型上限通配符
<? super T> : 泛型下限通配符
例如:
public class Fruit {
}
public class Apple extends Fruit {
}
public class Cherry extends Apple {
}
// 可以使用Fruit及其子类作为类型参数
public void out(List<? extends Fruit> list) {
System.out.println(list.toString());
}
// 可以使用Apple及其父类、父接口作为类型参数
public void output(List<? super Apple> list) {
System.out.println(list.toString());
}