行业知识
Java 中的泛型(两万字超全详解)
文章目录
- 前言
- 一、泛型概述
- 1. 什么是泛型?为什么要使用泛型?
- 2. 泛型使用场景
- 3. 泛型概述小结
- 二、泛型类
- 1. 泛型类的定义
- 2. 泛型类的使用
- 三、泛型接口
- 四、泛型方法
- 1. 泛型方法的定义
- 2. 泛型方法的使用
- 3. 泛型方法中的类型推断
- 五、类型擦除
- 1. 什么是类型擦除
- 2. 类型擦除的原理
- 3. 类型擦除小结
- 六、泛型通配符
- 1. 泛型的继承
- 2. 泛型通配符的引入
- 3. 什么是泛型通配符
- 4. 上界通配符
- 7. :被称作无限定的通配符。
-
���们已经讨论了,即只定义一个?符号。
-
无界通配符:? 代表了任何一种数据类型,能代表任何一种数据类型的只有 null。需要注意的是: 也是一个数据类型实参,它和 Number、String、Integer 一样都是一种实际的数据类型。
-
注意:Object 本身也算是一种数据类型,但却不能代表任何一种数据类型,所以 ArrayList 和 ArrayList 的含义是不同的,前者类型是 Object,也就是继承树的最高父类,而后者的类型完全是未知的;ArrayList 是 ArrayList 逻辑上的父类。
(1)ArrayList 在逻辑上表示为所有数据类型的父类,它可以代表 ArrayList、ArrayList、ArrayList中的某一个集合,但实质上它们之间没有继承关系。
举例如下:
public class GenericType {public static void main(String[] args) { ArrayList list01 = new ArrayList(123, 456); ArrayList list02 = list01; // 安全地向上转型 }}- 上述代码是可以正常编译运行的,因为 ArrayList 在逻辑上是 ArrayList 的父类,可以安全地向上转型。
(2)ArrayList 既没有上界也没有下界,因此,它可以代表所有数据类型的某一个集合,但我们不能指定 ArrayList 的数据类型。
举例如下:
public class GenericType {public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(null);// 编译正确 Object obj = list.get(0);// 编译正确list.add(new Integer(1));// 编译错误Integer num = list.get(0);// 编译错误 }}- ArrayList 集合的数据类型是不确定的,因此我们只能往集合中添加 null;而我们从 ArrayList 集合中取出的元素,也只能赋值给 Object 对象,不然会产生ClassCastException 异常(原因可以结合上界和下界通配符理解)。
(3)大多数情况下,可以用类型参数 代替 通配符。
举例如下:
static void isNull(ArrayList list) { ...}// 替换如下:static void isNull(ArrayList list) { ...}7. 表示了非限定通配符,因为 可以用任意数据类型来替代。
4、List 和 List 之间的区别是什么?
- 这道题跟上一道题看起来很像,实质上却完全不同。List 是一个不确定的未知类型的 List,而 List 是一个确定的 Object 类型的 List。
- List 在逻辑上是所有 List 的父类,你可以把 List、 List 等集合赋值给 List 的引用;而 List 只代表了自己这个泛型集合类,只能把 List 赋值给 List 的引用,但是 List 集合中可以加入任意类型的数据,因为 Object 类是最高父类。 举例如下:
List listOfAnyType;List listOfObject = new ArrayList();List listOfString = new ArrayList();List listOfInteger = new ArrayList(); listOfAnyType = listOfString;// 编译正确listOfAnyType = listOfInteger;// 编译正确listOfObjectType = listOfString;// 编译错误
12、Java 中 List 和原始类型 List 之间的区别。
-
该题类似于“List 和原始类型 List 之间的区别”。泛型数据类型是类型安全的,而且其类型安全是由编译器保证的,但原始类型 List 却不是类型安全的。你不能把 String 之外的任何其它类型的对象存入 List 中,而你可以把任何类型的对象存入原始 List 中。
-
使用泛型数据类型你不需要进行类型转换,但是对于原始类型,你则需要进行显式的类型转换。举例如下:
List listOfRawTypes = new ArrayList();listOfRawTypes.add("abc");listOfRawTypes.add(123);String item = (String) listOfRawTypes.get(0);// 获取元素时需要显式的类型转换// 编译器不报错,但运行时会产生 ClassCastException异常,因为 Integer不能被转换为 Stringitem = (String) listOfRawTypes.get(1); List listOfString = new ArrayList();listOfString.add("abcd");listOfString.add(1234);// 编译器直接报错item = listOfString.get(0); // 不需要显式的类型转换,编译器会自动转换总结
博主花了一周多的时间,对 Java 泛型的知识进行详细地整理总结。但是受限于个人的知识水平,导致篇幅可能过长,再加上排版的问题,不知道小伙伴们的最后的观感如何。
但是终于终于把 Java 泛型的知识整理完了(可能还有些遗漏,后面会慢慢补充的)。其中需要完善的地方,等过段时间再回来完善,如果文章中有什么错误和需要修改的地方,还望小伙伴们提出和批评指正,博主一定会尽快更改。谢谢大家!
最后,大家看后有收获的话,就给博主点个赞吧!下篇文章再见~~
-
- ArrayList 集合的数据类型是不确定的,因此我们只能往集合中添加 null;而我们从 ArrayList 集合中取出的元素,也只能赋值给 Object 对象,不然会产生ClassCastException 异常(原因可以结合上界和下界通配符理解)。
- 上述代码是可以正常编译运行的,因为 ArrayList 在逻辑上是 ArrayList 的父类,可以安全地向上转型。
-