笔友城堡 - 可定义的个人主页

前言

Java面试中偶尔会问泛型extendssuper中的区别?

简单记录一下,方便自己学习和查阅。

正文

上界通配符

<? extends T>

就是上界通配符,表示<>中是T或T的子类。

举个例子:

List<? extends Number> list;

表示:list 里存的是Number或其子类(如 Integer、Double)

  1. 读取

    Number n = list.get(0);   // OK
    Integer i = list.get(0);  // ❌ 编译错误

    为啥第2个错误?

    因为list里存放的是Number或者其某一个具体子类,但编译器不知道是哪一个,可能是Integer,也可能Double,所以编译错误。

    但是如果返回给其父类(父类引用指向子类),那就是OK。

  1. 写入

    list.add(10);      // ❌ 错误
    list.add(10.5);    // ❌ 错误
    list.add(null);    // ✅ 只有 null 允许

    编译器不知道list到底是List<Integer>?还是 List<Double>?或者其他的,为了避免类型不安全,禁止写入

只读
double sum(List<? extends Number> list) {
    double s = 0;
    for (Number n : list) {
        s += n.doubleValue();
    }
    return s;
}

下界通配符

<? super T>

就是下界通配符,表示<>中是某个T 或 T 的父类

List<? super Integer> list;

list里存的是Integer或其父类(Number、Object)。

  1. 写入

    list.add(10);      // ✅ ok
    list.add(20);      // ✅ ok

    因为放 Integer 一定是安全的。

  1. 读取

    Object o = list.get(0);     // ✅ ok
    Integer i = list.get(0);   // ❌ 错误

    Object是Integer的父类,可以转,但是list存储不一定是Integer,所以第二个是错误

只写
void addNumbers(List<? super Integer> list) {
    list.add(1);
    list.add(2);
}

PECS 原则

Producer → Extends

Consumer → Super

角色用谁
只往外拿数据(生产)<? extends T>
只往里放数据(消费)<? super T>

总结

关键字含义能往里放什么能往外取成什么
<? extends T>上限通配符❌ 不能放(除了 null)✅ 至少 T
<? super T>下限通配符✅ 至少 T❌ 只能当 Object
  1. extends 表示“只读不写”

  2. super 表示“只写难读”

  3. 生产者用 extends

  4. 消费者用 super

再简单一下:

  1. extends 表示 就是上界通配符,表示<>中是T或T的子类

  2. super 表示下界通配符,表示<>中是某个T或T的父类

参考文章

AI

相关网址

笔友城堡 - 可定义的个人主页

暂无评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

none
暂无评论...