1. 什么是泛型?

泛型(Generics)是 Java(以及其他许多编程语言)中的一种特性,允许在定义类、接口、方法时不指定具体类型,而是用一个 “类型占位符”(通常用大写字母如T、E、K、V表示)来代替,在使用时再指定具体类型。
简单说,泛型就是 “类型的参数化”—— 就像方法可以接收 “值作为参数”,泛型允许类 / 接口 / 方法接收 “类型作为参数”。

为什么要使用泛型?

核心价值是:在保证类型安全的前提下,提高代码的通用性和复用性,减少类型转换错误。

“不使用泛型” 和 “使用泛型” 的对比

反例(不使用泛型):

// 一个存储“任意数据”的容器类
class Container {
    private Object data; // 用Object接收任意类型

    public void setData(Object data) {
        this.data = data;
    }

    public Object getData() {
        return data;
    }
}

// 使用时
Container container = new Container();
container.setData("hello"); // 存入String
Integer num = (Integer) container.getData(); // 错误!试图把String转成Integer
// 编译时不报错,但运行时会抛出ClassCastException(类型转换异常)

正例(使用泛型):

// 泛型容器类,T是类型占位符
class Container<T> {
    private T data; // 用T表示“未来会指定的具体类型”

    public void setData(T data) {
        this.data = data;
    }

    public T getData() {
        return data;
    }
}

// 使用时指定具体类型(如String)
Container<String> container = new Container<>();
container.setData("hello"); // 只能存入String,其他类型编译时就报错
String str = container.getData(); // 无需强制转换,直接使用
// Integer num = container.getData(); // 编译时直接报错,提前避免错误

使用途径

网络返回值

比如你请求一个接口的时候,需要返回成功(不携带业务数据),成功(携带业务数据(类型由调用时传入的对象决定)),失败3种情况,使用使用泛型
定义类的使用需要使用说明是泛型T

public class Result<T>{}

定义方法的时候需要在前面说明,static后面加

public static <T> Result<T> success(){}

如以下案例:

package Result;
import lombok.Data;
@Data
public class Result<T>{
    private Integer code;
    private String msg;
    private T data;

    /**
     * 成功结果,不携带业务参数
     * @return
     * @param <T>
     */
    public static <T> Result<T> success(){
        Result<T> result = new Result<T>();
        result.code=1;
        result.msg="成功";
        return result;
    }

    /**
     * 携带业务数据的成功结果
     * @param object
     * @return
     * @param <T>
     */
    public static <T> Result<T> success(T object){
        Result<T> result = new Result<T>();
        result.code=1;
        result.msg="成功";
        result.data=object;
        return result;
    }

    /**
     * 失败结果
     * @param errorMsg
     * @return
     * @param <T>
     */
    public static <T> Result<T> error(String errorMsg){
        Result<T> result=new Result<T>();
        result.code=0;
        result.msg=errorMsg;
        return result;
    }
    }

在调用的时候

成功结果,不携带业务参数

2025-09-01T06:33:04.png

成功结果,携带业务参数

比如需要传输一个实体类数据

public class User {
    private int id;
    private String name;
    private int age;
}

就可以直接传入T object这里
2025-09-01T06:48:42.png

失败结果,修改其他属性

2025-09-01T06:50:38.png