【java基础】泛型的通配符(extends,super,?)

基本概念

如果不使用通配符,那么我们在使用了泛型之后就不允许类型参数发生改变了,但是有了通配符就可以更加灵活的控制类型参数,类型参数可以发生改变。下面准备了3个类用于演示

public class A {

}
public class B extends A {

}
public class C extends B {

}

通配符extends

我们使用这个通配符可以限制类型参数是某个类(接口)或者是其子类。

    public static <T extends AutoCloseable> void close(T t) {
        try {
            t.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

上面代码中我就限定了T是AutoCloseable的实现类,由于是它的实现类,那么AutoCloseable的方法当然也就可以调用了。

如果不需要用到T,那么就可以使用?代替,个数如下

    public static void printList(List<? extends B> list) {
        for (B b : list) {
            System.out.println(b);
        }
    }

上面的List<? extends B>就代表传入的List只能是B类或其子类类型的集合
需要注意的是,对于extends,我们不能够填充元素,也就是写操作

    public static void printList(List<? extends B> list) {
        list.add(new B());
    }

上面代码会出现错误

在这里插入图片描述

原因就是编译器知道要传入的参数是某个类型的子类型,但不知道具体是哪个子类型

举个例子就是List<? extends B>可以是List<B>和List<C>,假设D为B的子类,那么还可以为List<D>,以此类推,子类是无限制的,所以使用extends肯定就是不能进行写操作了,原因就是子类型无法引用父类型。好比一个List<C>存储一个B元素不合理吧


通配符super

这个通配符可以限制参数类型为某个类或者为其父类

    public static void downLimit(List<? super B> list) {
        // list.add(new C());
        // list.add(new B());
        for (Object o : list) {
            System.out.println(o);
        }
    }

List<? super B>就表示传入的类型为B或B的父类的集合。对于super,由于不知道具体传入的是什么,所以就只能使用Object接收了。

对于super,我们可以填充元素

    public static void downLimit(List<? super B> list) {
        list.add(new C());
        list.add(new B());
    }

对于这种情况,可以理解为List<? super B>可以是List<B>或者List<A>或者其他的父类集合,那么我们我们不管哪种情况,存储B和C都是合理的吧,父类引用子类没有任何问题。

下面就是java核心卷中给出的总结

带有超类型限定的通配符允许你写入一个泛型对象,而带有子类型限定的通配符允许你读取一个泛型对象。

无限定通配符?

下面就来看一个例子分析一下一个Tool类

public class Tool<T> {

    private T info;

    public T getInfo() {
        return info;
    }

    public void setInfo(T info) {
        this.info = info;
    }
}

对于Tool<?>会有以下2个方法

? getInf()
void setInfo(?)

对于getInfo,可以调用,返回值只能赋给Object。对于setInfo,根本不能调用(如果调用只能传入null),因为不知道?是什么。

对于?,通常都是为了避免使用泛型方法。<?>就表示匹配任意类型,和extends和super一起使用分别就表示上限和下限

总结

java核心卷在泛型这章讲的真的是晦涩难懂,如果上面有说错的地方,欢迎大家私信或者评论区指出。

关于泛型的更多知识,参考以下内容

泛型程序设计基础
类型擦除、桥方法、泛型代码和虚拟机
泛型的限制及其继承规则
泛型的通配符(extends,super,?)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秃头披风侠.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值