Java那些事—泛型通配符

简介: Java的类型通配符,可以出现在类、方法上面。最常用的方式就是集合类,例如List,Set等类上面。通配符类型有泛型参数 List有无类型标识 List< ? >有通用的标识 List< object >边界通配符 List边界通配符 List本文主要讨论的是最后的关于边界的通配符类型。

Java的类型通配符,可以出现在类、方法上面。最常用的方式就是集合类,例如List,Set等类上面。

通配符类型

有泛型参数 List

有无类型标识 List< ? >

有通用的标识 List< object >

边界通配符 List

边界通配符 List

本文主要讨论的是最后的关于边界的通配符类型。

看一个例子

public static void main(String[] args) { List bList = new ArrayList(); bList.add(new A()); bList.add(new B()); bList.add(new C()); A a3 = bList.get(0); B b3 = bList.get(0); C C3 = bList.get(0); List bExtends = new ArrayList(); bExtends.add(new A()); bExtends.add(new B()); bExtends.add(new C()); A a1 = bExtends.get(0); B b1 = bExtends.get(0); C C1 = bExtends.get(0); List bSuper = new ArrayList(); bSuper.add(new A()); bSuper.add(new B()); bSuper.add(new C()); A a2 = bSuper.get(0); B b2 = bSuper.get(0); C C2 = bSuper.get(0); }}class A { String a = "a";}class B extends A { String b = "b";}class C extends B { String c = "c";}

有三个类,继承关系是A < B < C。

然后声明了三个数组,list,extends,super.

上面的代码是编译不通过的。分别在第3、7、11-13、16、19、22-24行。

原理分析

List 得到的是B及B的子类的一个集合。

List 得到的是B及B的父类的一个集合。

List 得到的是一个B的集合。

? extends B 声明了上界标识符、不定下界,而add(E e)的时候,编译器无法确定e需要分配的声明类型,虽然有实际类型,这个地方跟多态不一致,所以编译器不通过;而get(int i)的操作,会获取到一个肯定是B的元素,故是安全的。

? super B正相反,声明的是下界标识符、不定上界(Object),当add(E e)的时候,添加的是子类型,子类型向上转型是安全的;get(int i)的时候,并不能确定拿到的会是一个怎样的类型,可能是Object,也能是A,故也是违规的。

B 声明的是上下界为B。add(E e)按照多态性,可以添加为B的类型及其子类型;get(int i)返回的必然是B的类型。

代码错误验证

按照第1条解释,第3、11-13行的错误符合解释。

按照第2条解释,第19、22-24行的错误符合解释。

第7、16行是由于向下转型是不安全的,股编译错误。

小结

extends和super别定义了上下限,结论如下面的表格

extendssuperTaddunsafesafesafegetsafeunsafesafe

欢迎工作一到五年的Java程序员朋友们加入Java架构开发:744677563

本群提供免费的学习指导 架构资料 以及免费的解答

不懂得问题都可以在本群提出来 之后还会有职业生涯规划以及面试指导

相关文章
|
16天前
|
存储 Java 编译器
深入理解 Java 泛型和类型擦除
【4月更文挑战第19天】Java泛型是参数化类型,增强安全性与可读性,但存在类型擦除机制。类型擦除保证与旧版本兼容,优化性能,但也导致运行时无法访问泛型信息、类型匹配问题及数组创建限制。为应对这些问题,可使用Object类、instanceof运算符,或借助Guava库的TypeToken获取运行时类型信息。
|
24天前
|
JavaScript Java 编译器
Java包装类和泛型的知识点详解
Java包装类和泛型的知识点的深度理解
|
2月前
|
Java
java中的泛型类型擦除
java中的泛型类型擦除
14 2
|
4天前
|
Java
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识
JAVA难点包括异常处理、多线程、泛型和反射,以及复杂的分布式系统知识。入坑JAVA因它的面向对象特性、平台无关性、强大的标准库和活跃的社区支持。
16 2
|
9天前
|
安全 Java 编译器
【JAVA】泛型和Object的区别
【JAVA】泛型和Object的区别
|
11天前
|
存储 算法 Java
滚雪球学Java(20):Java泛型与枚举:提升代码灵活性与可读性
【4月更文挑战第9天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
22 1
滚雪球学Java(20):Java泛型与枚举:提升代码灵活性与可读性
|
11天前
|
Java
|
11天前
|
安全 Java 机器人
|
12天前
|
存储 安全 Java
每日一道Java面试题:说一说Java中的泛型?
今天的每日一道Java面试题聊的是Java中的泛型,泛型在面试的时候偶尔会被提及,频率不是特别高,但在日后的开发工作中,却是是个高频词汇,因此,我们有必要去认真的学习它。
17 0
|
13天前
|
安全 Java 编译器
Java基础教程(14)-Java中的枚举类,泛型和注解
【4月更文挑战第14天】枚举类型(enum)是固定常量集合,Java中用`enum`定义。特点包括:使用enum关键字,定义类型名和值,可独立或嵌入定义,可实现接口,定义变量和方法。枚举在switch语句中适用,每个枚举值在JVM中唯一,不能继承Enum类。