Java泛型(补档)

核心概念

Java 泛型是 Java SE 1.5 引入的一项重要特性,它的核心思想是 参数化类型(Parameterized Types),即通过将数据类型作为参数传递给类、接口或方法,使代码能够灵活地处理多种类型,同时保证类型安全性。


一、基本语法

1. 泛型类/接口

在类名后添加类型参数 <T>,T 是占位符(可以是任意标识符),声明后类的占位符会被替换成对应类型

java 复制代码
public class Box<T> {
    private T content;
    public void setContent(T content) { this.content = content; }
    public T getContent() { return content; }
}

// 使用
Box<String> stringBox = new Box<>();
stringBox.setContent("Hello");
String value = stringBox.getContent(); // 无需强制转换

2.泛型接口

java 复制代码
public interface ITest<T> {
    void show(T t);
}

public class TestImpl implements ITest<String> {
    @Override
    public void show(String t) {
        System.out.println(t);
    }
}

3.泛型方法

  • 作为传参:在方法返回类型前声明类型参数 <T>:
java 复制代码
//   修饰符  <T>  返回值类型 方法名(T 变量名){
public <T> void printArray(T[] array) {
    for (T element : array) {
        System.out.println(element);
    }
}

// 调用时可显式指定类型或由编译器推断
printArray(new Integer[]{1, 2, 3});
  • 作为返回值:使用 Class<T> 参数传递类型信息
java 复制代码
public <T> T convert(Object input, Class<T> targetType) {
    if (targetType == String.class) {
        return targetType.cast(input.toString()); // 转成 String
    } else if (targetType == Integer.class) {
        return targetType.cast(Integer.parseInt(input.toString())); // 转成 Integer
    }
    throw new IllegalArgumentException("不支持的类型: " + targetType);
}

//调用
String strResult = convert(123, String.class);       // 返回 "123"(String 类型)
Integer intResult = convert("456", Integer.class);   // 返回 456(Integer 类型)

二、泛型通配符<?>

1. 无界通配符 <?>

  • 作为传参:表示接受任何类型
java 复制代码
public void processList(List<?> list) {
    for (Object elem : list) { /* ... */ }
}
  • 作为返回值:表示返回任何类型
java 复制代码
    public List<?> getData() {
        List<Food> resultList = new ArrayList<>();
        return resultList;
    }

2. 上界通配符 <? extends T>

接受 T 或其子类(适合读取数据):

java 复制代码
public double sum(List<? extends Number> list) {
    double sum = 0.0;
    for (Number num : list) { sum += num.doubleValue(); }
    return sum;
}

3. 下界通配符 <? super T>

接受 T 或其父类(适合写入数据):

java 复制代码
public void addNumbers(List<? super Integer> list) {
    list.add(1);
    list.add(2);
}

4. PECS 原则(Producer-Extends, Consumer-Super)

  • 生产者(Producer):提供数据时用 extends(如 List<? extends T>)
  • 消费者(Consumer):消费数据时用 super(如 List<? super T>)

三、实际应用场景

1. REST API 响应封装

java 复制代码
public class ApiResponse<T> {
    private int code;
    private String message;
    private T data; // 泛型数据

    // 构造方法和Getter/Setter
    public static <T> ApiResponse<T> success(T data) {
        ApiResponse<T> response = new ApiResponse<>();
        response.setCode(200);
        response.setData(data);
        return response;
    }
}

// 使用
ApiResponse<User> userResponse = ApiResponse.success(user);
ApiResponse<List<Product>> productResponse = ApiResponse.success(products);

2.Java 的集合框架(如 ArrayList<T>, HashMap<K,V>)

java 复制代码
List<String> names = new ArrayList<>();
names.add("Alice");
String name = names.get(0); // 不需要强制转换

3.工具类方法

泛型方法可用于编写通用的工具类,例如排序、查找等。

java 复制代码
public static <T extends Comparable<T>> T max(T a, T b) {
    return a.compareTo(b) > 0 ? a : b;
}
相关推荐
1024奇点7 小时前
【仓颉语言入门 · 第二篇 第 22 课】
开发语言·ide·开源
Warren2Lynch8 小时前
C4 模型详解:利用 Visual Paradigm 可视化软件架构的综合指南
开发语言·uml
天河归来8 小时前
第三方接口不稳定,如何让核心任务继续完成
java·大数据
Knight_AL9 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
FRing039 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
by2099910 小时前
C++ 智能指针的所有权与使用
开发语言·c++·经验分享
砚底藏山河10 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
IT召唤狮10 小时前
开源企业级零信任项目Pangolin,零信任能挡住PHP核弹漏洞吗?
开发语言·开源·php
知已难寻10 小时前
03 · OpenStack的计算管理 Nova
运维·服务器·开发语言·云原生·云计算·openstack·开源软件
Rover Ramble10 小时前
C++ 用互斥锁实现读写锁
开发语言·c++