通俗易懂理解泛型

将通过一个故事来解释 Java 泛型,并结合代码示例说明各种使用场景。

故事场景:快递包裹系统

假设你在一家快递公司工作,负责处理各种类型的包裹。为了让工作更高效,公司引入了一套 "通用容器" 系统(类似于 Java 泛型)。

1. 最初的问题:类型不安全的容器

一开始,公司使用普通的箱子来装所有物品:

java

typescript 复制代码
// 普通箱子,可以装任何东西
class Box {
    private Object item;

    public void put(Object item) {
        this.item = item;
    }

    public Object get() {
        return item;
    }
}

// 使用箱子
Box box = new Box();
box.put("一本书"); // 放入字符串
String book = (String) box.get(); // 需要强制类型转换

问题

  • 箱子可以装任何类型的物品
  • 取出物品时需要手动进行类型转换
  • 如果放错类型(如放入 Integer),运行时会报错(ClassCastException)

2. 引入泛型:类型安全的容器

后来,公司发明了 "类型标签" 箱子,可以在创建时指定能装的物品类型:

java

typescript 复制代码
// 泛型箱子,使用类型参数<T>
class Box<T> {
    private T item;

    public void put(T item) {
        this.item = item;
    }

    public T get() {
        return item;
    }
}

// 使用泛型箱子
Box<String> stringBox = new Box<>();
stringBox.put("一本书"); // 只能放String
String book = stringBox.get(); // 无需强制类型转换

Box<Integer> intBox = new Box<>();
intBox.put(123); // 只能放Integer
Integer number = intBox.get();

优点

  • 在编译时检查类型安全
  • 无需手动类型转换
  • 代码更清晰,可读性更高

泛型的使用场景

1. 泛型类(如 Box)

java

arduino 复制代码
// 自定义泛型类
class Pair<K, V> {
    private K key;
    private V value;

    public Pair(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() { return key; }
    public V getValue() { return value; }
}

// 使用
Pair<String, Integer> pair = new Pair<>("年龄", 18);
String key = pair.getKey(); // String类型
Integer value = pair.getValue(); // Integer类型

2. 泛型方法

java

ini 复制代码
// 泛型方法:交换数组中两个元素的位置
public static <T> void swap(T[] array, int i, int j) {
    T temp = array[i];
    array[i] = array[j];
    array[j] = temp;
}

// 使用
String[] names = {"Alice", "Bob", "Charlie"};
swap(names, 0, 2); // 交换names[0]和names[2]

3. 泛型接口

java

typescript 复制代码
// 泛型接口:比较器
interface Comparator<T> {
    int compare(T o1, T o2);
}

// 实现泛型接口
class StringLengthComparator implements Comparator<String> {
    @Override
    public int compare(String s1, String s2) {
        return s1.length() - s2.length();
    }
}

4. 上限通配符(? extends T)

假设公司有一个 "电子产品" 分类,所有电子产品都继承自Electronics类:

java

scala 复制代码
class Electronics {}
class Phone extends Electronics {}
class Laptop extends Electronics {}

// 只能存放Electronics及其子类的箱子
void printElectronics(Box<? extends Electronics> box) {
    Electronics item = box.get(); // 安全,因为一定是Electronics类型
    // box.put(new Phone()); // 错误!不能放入任何对象(除了null)
}

用途:读取数据,不写入数据

5. 下限通配符(? super T)

假设公司有一个 "员工" 分类,所有员工都继承自Employee类:

java

scala 复制代码
class Employee {}
class Manager extends Employee {}
class CEO extends Manager {}

// 可以存放Manager及其父类的箱子
void addManager(Box<? super Manager> box) {
    box.put(new Manager()); // 安全,因为Manager及其子类都可以存入
    box.put(new CEO()); // 安全,CEO是Manager的子类
    // Employee emp = box.get(); // 错误!返回类型是? super Manager,无法确定具体类型
}

用途:写入数据,不读取数据

6. 无界通配符(?)

java

csharp 复制代码
// 可以存放任何类型的箱子
void printBox(Box<?> box) {
    Object item = box.get(); // 安全,因为所有类型都是Object的子类
    System.out.println(item);
    // box.put("hello"); // 错误!不能放入任何对象(除了null)
}

7. 泛型擦除

Java 泛型在编译后会被擦除为原始类型:

java

ini 复制代码
Box<String> stringBox = new Box<>();
Box<Integer> intBox = new Box<>();

System.out.println(stringBox.getClass() == intBox.getClass()); // true
// 运行时,两者都是Box类型

总结

泛型的核心思想

  • 将类型参数化,在使用时指定具体类型

  • 提供编译时类型安全检查

  • 避免手动类型转换

  • 增强代码复用性

使用场景

  1. 泛型类:容器类(如 Box、List)

  2. 泛型方法:通用工具方法

  3. 泛型接口:定义通用行为

  4. 上限通配符:读取数据(Producer Extends)

  5. 下限通配符:写入数据(Consumer Super)

  6. 无界通配符:处理任意类型

  7. 泛型擦除:Java 泛型的实现机制

通过这个故事,你可以把 Java 泛型想象成 "类型安全的容器",就像快递公司的标签系统一样,在编译时就确保类型正确,让代码更加健壮和易读。

相关推荐
周杰伦的稻香1 小时前
MySQL中的空间碎片率计算分析
android·数据库·mysql
用户092 小时前
MVI架构如何改变Android开发模式
android·面试·kotlin
梦终剧3 小时前
【Android之路】.sp和界面层次结构
android
2501_916008893 小时前
iOS 26 软件性能测试全流程,启动渲染资源压力对比与优化策略
android·macos·ios·小程序·uni-app·cocoa·iphone
zh_xuan3 小时前
Android Handler源码阅读
android
雪饼android之路4 小时前
【Android】 android suspend/resume总结(3)
android·linux
00后程序员张4 小时前
iOS 26 兼容测试实战,机型兼容、SwiftUI 兼容性改动
android·ios·小程序·uni-app·swiftui·cocoa·iphone
molong9314 小时前
Android 应用配置跳转微信小程序
android·微信小程序·小程序
2501_915106325 小时前
iOS 可分发是已经上架了吗?深入解析应用分发状态、ipa 文件上传、TestFlight 测试与 App Store 审核流程
android·ios·小程序·https·uni-app·iphone·webview
安东尼肉店13 小时前
Android compose屏幕适配终极解决方案
android