Java——泛型与类型通配符"?"

泛型与类型通配符

泛型的特性

泛型只在编译阶段有效。看下面的代码:

List<String> stringArrayList = new ArrayList<String>();
List<Integer> integerArrayList = new ArrayList<Integer>();

Class classStringArrayList = stringArrayList.getClass();
Class classIntegerArrayList = integerArrayList.getClass();

if(classStringArrayList.equals(classIntegerArrayList)){
    Log.d("泛型测试","类型相同");
}

输出结果:D/泛型测试: 类型相同。

通过上面的例子可以证明,在编译之后程序会采取去泛型化的措施。也就是说Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。

对此总结成一句话:泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。

类型通配符 使用的原因

假设需要定义一个方法,该方法里有一个集合形参,集合形参的元素类型是不确定的,那应该怎么定义呢?
在下面代码中:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
重要解释:Foo 是 Bar 的子类型 但G不是G的子类型 ,因为他们的类型是G

在这里插入图片描述

1. 使用类型通配符

为了表示各种泛型 List 的父类,可以使用类型通配符(?),将问号作为类型实参传给 List 集合,写作:List<?>(意思是元素类型未知的 List),此问号的元素类型可以匹配任何类型。

在这里插入图片描述
但这种通配符仅表示它是各种泛型 List 的父类,并不能把元素加入到其中。
如下代码会编译错误:
在这里插入图片描述

2. 设定类型通配符的上限

考虑特殊情形:程序不希望List<?>是任何泛型 List 的父类,只希望它代表某一类泛型 List 的父类。考虑一个简单的绘图程序,下面先定义三个形状类:
在这里插入图片描述
在这里插入图片描述
上面定义了三个形状类,其中shape 是一个抽象父类,该抽象父类有两个子类:Circle 和 Rectangle。接下来定义一个 Canvas 类,该画布类可以画数量不等的形状(Shape 子类的对象),那应该如何定义这个 Canvas 类呢?
考虑如下 Canvas 实现类。
在这里插入图片描述
注意上面的 drawAll () 方法的形参类型是 List,而 List 并不是 List的子类型,因此,下面代码将引起编译错误。
在这里插入图片描述
关键在于 List<Circle> 并不是 List <Shape>的子类型,所以不能把 List<Circle> 对象当成 List <Shape>使用。为了表示List 的父类,可以考虑使用 List<?> ,把Canvas 改成如下形式:
在这里插入图片描述
上面程序使用了通配符来表示所有的类型

在这里插入图片描述
在这里插入图片描述

3. 设定类型形参的上限

Java 泛型不仅允许在使用通配符形参时设定上限,而且可以在定义类型形参时设定上限,用于表示传给该类型形参的实际类型要么是该上限类型,要么是该上限类型的子类。下面程序示范了这种用法:
在这里插入图片描述
在这里插入图片描述
在一种更极端的情况下,程序需要为类型形参设定多个上限(至多有一个父类上限,可以有多个接口上限),表明该类型形参必须是其父类的子类(是父类本身也行),并且实现多个上限接口。如下代码所示:
在这里插入图片描述
与类同时继承父类、实现接口类似的是,为类型形参指定多个上限时,所有的接口上限必须位于类上限之后。也就是说,如果需要为类型形参指定类上限,类上限必须位于第一位。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值