泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
引入泛型的意义在于:
适用于多种数据类型执行相同的代码(代码复用)
(泛型这个东西理论有点抽象 还是实际的代码例子来理解会易懂一点)
首先我们常见的常规类:
public class Box {
private String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
}
然后我们改造成泛型类:类前面加上< T > :
public class Boxs<T>{
private T data;
private String code;
private String traceId;
public Boxs() {}
private Boxs(T data, String code, String traceId) {
this.data = data;
this.code = code;
this.traceId = traceId;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getTraceId() {
return traceId;
}
public void setTraceId(String traceId) {
this.traceId = traceId;
}
public void setData(T data) {
this.data = data;
}
public T getData() {
return data;
}
}
这里的T代表泛型参数 起什么都可以 只不过一般规范喜欢叫T。
这里理解上要注意
定义了刚才这个泛型类之后 我们在test main函数中 实例一下,这里就体现出泛型的强大了 我们可以随意界定任何类型 来确定泛型中的这个T, 比如 integer,string, 而且除了泛型参数T 类中其他的常规参数 也可以正常使用 和正常类没区别:
/**
* 定义了一个Boxs泛型类对象
* */
Boxs<Integer>boxOfInt = new Boxs<>();
boxOfInt.setData(1);
System.out.println(boxOfInt.getData());
Boxs<String>boxOfStr = new Boxs<>();
boxOfStr.setData("apple");
boxOfStr.setCode("007");
System.out.println(boxOfStr.getData());
这里你可以用任意类型来替换 T ,但是你会发现,定义泛型类的时候 T是任意类型 但是你实例化这个Boxs类的时候 这里的T需要明确类型。
了解了泛型类之后,自然就引出了泛型方法——也就是方法的返回值是泛型, 可以看到上面的泛型类代码中已经有一个简单的泛型方法:
public T getData() {
return data;
}
这里返回值是泛型T 也就是 set进去的T是什么类型 你调用get方法的时候取出来的T就是什么类型
比如在刚才的Boxs< T > 泛型类中我们 加一个静态的泛型方法 用来得到一个Boxs< T >类实例:
private Boxs(T data, String code, String traceId) {
this.data = data;
this.code = code;
this.traceId = traceId;
}
public static <T> Boxs<T>create(T data, String code, String traceId) {
return new Boxs<>(data, code, traceId);
}
这里对比之前的get方法 这是把方法类型从T 换成了类< T > ,
最后说一个泛型类和泛型方法 最最常见的应用场景,应该大多数java程序员都见过: 就是web开发中 统一返回前端数据类
web应用中 要统一一个 返回前端的数据结构,就会用的泛型
比如
public class Result<T> implements Serializable{
int code //http状态码
boolean success //请求是否成功
T data //业务数据
}
什么叫参数限制呢 之前T是什么类型都可以 ,但是你不想T的类型完全无限制,这种情况 可以用java的继承思想 来用父类限定子类
写法是 < T extends Father>
来个例子, 比如我们知道 java中有一个 Number 类型,它是八种数据类型包装类对象的父类:
Integer、Double、Float、Short、Long、Boolean、Byte、Character
给刚才的Boxs 加上 限制:
public class Boxs<T extends Number>{ ...........}