泛型通配符“?“的使用详解

1 使用背景

在使用泛型时,C<SuperA>C<A> 是并列的两个类,没有子父类关系,也就不能相互赋值。如 ArrayList<Object> 与 ArrayList<String> 没有关系,这使得在给方法传参时,通用性很差。使用通配符C<?>能使得代码的兼容性更好。

2 类型通配符?的使用

当带上类型通配符?,如List<?>时,可以理解为集合内的数据类型是任何可能的类型,在继承关系上用区间表示就是(-∞,+∞),可以理解为所有明确类型List<>的父类。

2.1 带类型通配符数据的读写

a. 读带类型通配符的数据

由于?代表了任何可能的类型,所以在接收读取到的数据时,一般要用通用型的基类Object来接收,也可以将其强转为指定的类型。

public static void main(String[] args) {
        List<String> list1 = new ArrayList<>();
        list1.add("abc");
        List<?> list= null;
        list = list1;
        Object o = list.get(0);
        String str = (String)list.get(0);
    }

b.将数据写入带类型通配符的结构

由于?代表了任何可能得类型,所以在写入数据时,我们要写入的任何数据类型都可能是其子类,而且因为不能把子类的数据直接赋给父类数据,所以不能写入任何数据。

唯一例外的是可以写入null,因为null是任何引用型数据变量的默认值。

2.2 类型通配符的使用环境

类型通配符主要就是应用在传参、赋值等的读取、接收数据的场合,其他的场景使用较少,而且如以下几类是语法所不允许的:

(1)不能声明一个带通配符?的泛型方法

public <?> void test(ArrayList<?> list){}

(2)不能声明一个带通配符?的泛型类

public class TestClass(){}

(3)不能定义一个带通配符?的集合

List<?> list = new ArrayList<?>();
2.3 有限制条件的通配符的使用
  • ? super A ==> ? ≥ A

    读取数据:List <? super A> :若B是A的父类,可以将List<A>或List<B>赋值给List<? extends A>。即A和A的父类的数据都可以被读取。

    写数据:表示该泛型可能是较大的类型,这时B和B的子类一定是'?'类的子类,这时,可以往里面写入B和B的子类类型的数据。

  • ? extends A ==> ? ≤ A

    读取数据:List<? extends A> :若B是A的子类,可以将List<A>或List<B>赋值给List<? extends A>。即A或A的子类的数据都可以被读取。

    写数据:表示该泛型可能是较小的类型,这时A和A的父类一定是'?'类的父类,这时,不能把父类的数据写入子类中,即不能写入除null外的数据。

  • ? 可以理解为 (-∞, +∞') 这时除null外的任何类型的数据都不能写入。

  • 通配符不能带双向限制条件,即同时有extends和super。

参考:尚硅谷-宋红康-Java基础:尚硅谷Java零基础全套视频教程(宋红康2023版,java入门自学必备)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值