泛型的使用
优点:
- 编译时,检查添加元素类型,提高安全性
- 减少了类型转换次数,提高效率
- 泛型是一种表示数据类型的数据类型
泛型的语法
- 声明
interface 接口 {} 和 class 类 <K,V> {}
说明:
1) 其中,T、K、V并不代表值,而是表示类型
2)任意字母都可以,通常T表示类型Type
3)泛型 指定的类型必须是引用数据类型
4)在给泛型定义类型的时候,可以传入泛型的类型或者是子类型
5)没有指定泛型,默认泛型是Object类型
ArrayList arrayList = new ArrayLIst()
自定义泛型
6点注意事项
- Tiger后面泛型,所以我们把 tiger成为自定义泛型类
- T、R、M、 泛型标识符,一般是单个大写
- 泛型标识符可以有多个
- 普通成员可以使用泛型(属性、方法)
- 使用泛型的数组不能初始化(不知道是什么数据类型,不能开辟多少空间)
- 静态方法中不能使用泛型
自定义泛型接口
- 接口中,静态成员也不能使用泛型
- 泛型接口的类型,在接口继承或者接口实现的时候确定
- 没有指定类型,默认为Object
自定义泛型方法
- 泛型方法,可以定义在普通类中,可以定义在泛型类中
- 当泛型方法被调用时,类会确定
- public void eat(E e ) {} 修饰符后没有<R,R ... >eat 方法不是泛型方法,而是使用了泛型
使用案例
package JavaTest;
import java.util.ArrayList;
/**
* @author 李志强(lzq6882022 @ 163.com)
* @version 1.0
*/
public class CustomMethodGeneric {
public static void main(String[] args) {
Car car = new Car();
car.fly("宝马", 100);//当调用方法时,传入参数,编译器,就会确定类型
System.out.println("=======");
car.fly(300, 100.1);//当调用方法时,传入参数,编译器,就会确定类型
//测试
//T->String, R-> ArrayList
Fish<String, ArrayList> fish = new Fish<>();
fish.hello(new ArrayList(), 11.3f);
}
}
class Car {//普通类
public void run() {//普通方法
}
//说明 泛型方法
//1. <T,R> 就是泛型
//2. 是提供给 fly 使用的
public <T, R> void fly(T t, R r) {//泛型方法
System.out.println(t.getClass());//String
System.out.println(r.getClass());//Integer
}
}
class Fish<T, R> {//泛型类
public void run() {//普通方法
}
public <U, M> void eat(U u, M m) {//泛型方法
}
//说明
//1. 下面 hi 方法不是泛型方法
//2. 是 hi 方法使用了类声明的 泛型
public void hi(T t) {
}
//泛型方法,可以使用类声明的泛型,也可以使用自己声明泛型
public <K> void hello(R r, K k) {
System.out.println(r.getClass());//ArrayList
System.out.println(k.getClass());//Float
}
}
泛型的继承和通配符
- 泛型不具备继承性
List<Object> list = new ArrayList<String>(); // 不允许
<?>:支持任意泛型类型<?extends A>:支持A类以及A类的子类,规定了泛型上限<? super A>: 支持A类以及A类的父类,不限于直接父类,规定了泛型的下限