JAVA-泛型通配符的上界和下界

发布于:2025-06-30 ⋅ 阅读:(19) ⋅ 点赞:(0)

在 Java 泛型中,通配符(Wildcard) 用于表示未知的类型。为了增强灵活性和安全性,Java 提供了对通配符的上界(Upper Bound)下界(Lower Bound) 的限制。


🟢 一、通配符概述

  • 基本通配符:?
    • 表示未知类型。
    • 示例:List<?> 表示一个元素类型未知的列表。

⚠️ 使用 List<?> 后,不能向其中添加除 null 外的任何元素(因为编译器不知道具体类型),但可以读取为 Object


🔺 二、通配符的上界(Upper Bound Wildcard)

✅ 语法:

? extends T
  • 表示“某个未知类型,它是 T 的子类型”。
  • 适用于“只读不写”的场景。

✅ 示例:

List<? extends Number> list = new ArrayList<Integer>();
  • 可以读取元素为 Number 类型:

    Number num = list.get(0);
    
  • ❌ 不允许添加元素(除了 null):

    list.add(123); // 编译错误!不知道实际类型是 Integer 还是 Double 等
    

✅ 用途:

  • 当你只需要从集合中读取数据,并希望它能接受多种子类型时使用。

🔻 三、通配符的下界(Lower Bound Wildcard)

✅ 语法:

? super T
  • 表示“某个未知类型,它是 T 的父类型”。
  • 适用于“只写不读”的场景。

✅ 示例:

List<? super Integer> list = new ArrayList<Number>();
  • ✅ 可以添加 Integer 类型的对象:

    list.add(10);
    
  • ❌ 读取时只能作为 Object 类型:

    Object obj = list.get(0); // 无法知道具体是 Number、Object 还是其他父类
    

✅ 用途:

  • 当你需要将某种具体类型的数据写入集合,并且该集合的类型必须是它的父类时使用。

🟡 四、对比总结

通配符形式 含义 可否添加元素 可否读取元素 典型用途
? 任意类型 ✅(作为 Object 通用只读集合
? extends T T 或其子类 ✅(作为 T 读取特定类型的集合
? super T T 或其父类 ✅(作为 Object 写入特定类型的集合

🧠 小技巧:PECS 原则(Producer Extends, Consumer Super)

这是理解泛型通配符的经典原则:

  • Producer(生产者) → 使用 extends(只读)
  • Consumer(消费者) → 使用 super(只写)

示例代码:

public static void copy(List<? extends Number> source,
                        List<? super Number> dest) {
    for (Number number : source) {
        dest.add(number); // 写入到 dest
    }
}

📝 总结

  • 使用 ? extends T 来限定上界,适合读操作。
  • 使用 ? super T 来限定下界,适合写操作。
  • 结合 PECS 原则,可以更安全地使用泛型集合。

网站公告

今日签到

点亮在社区的每一天
去签到