介绍
Java 泛型(generics)是 JDK1.5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型,在此之前java都是使用object来进行完成这种功能,但是object的向下转型会带来一些类型转化的问题,所以才加入了泛型。
讲解
一、泛型的引入
在jdk1.5以前想要实现类似于C++模板的功能时,一般都是使用object实现,如:实现一个point类,里面有x、y两个数据成员,但是对于x、y类似是不确定的,有时候需要int型的x、y,有时候需要float型的x、y。其实现如下所示:
1 | class Point{ |
这种做法是基本满足使用要求,但是如果在某些情况下,很容易发生Object向下转型带来的问题,如以下代码:
1 |
|
运行时就会发错误(如下图),即类型转化所带来的问题,并且这种错误,在编译时不会显示出来,只会在运行时显示,所以针对这种情况java引进了泛型。

所以如果使用泛型改写上述代码就应该是这样
1 | class Point<T>{ |
使用起来就变成了这样Point<Integer>point = new Point<>(),如果这时候调用如果类型不对,会在编译的时候就爆出错误(如下图),方便开发人员及时的处理错误。

另外如果申明了泛型,但是使用时不加<类型>,java还是会把里面的T当作Object处理,如上面的Point<Integer>point = new Point<>(),我这样用Point point = new Point(),并不会报错,而且会把x、y直接当作Object类型,也算时一种向下兼容,防止以前写的代码出问题。
二、泛型的使用
1.泛型类
泛型类使用起来比较简单,如上面的Point,就是泛型类的一种使用,不过需要注意的是泛型的参数字母可以任意定义,并且参数数量也没有什么限制,在这里就不过多举例。
1 | //此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型 |
如何实例化泛型类:
1 | Generic<Integer> genericInteger = new Generic<Integer>(123456); |
2.泛型接口
泛型接口定义和泛型类相似,可以参考如下代码
1 | interface IMessage<T>{ |
但是值得注意的是,接口实现时,有两种方式:
- 继续使用泛型,不指定类型:
1 | class IMessageImp <T> implements IMessage<T>{ |
- 使用具体的类型
1 | class IMessageImp implements IMessage<String>{ |
两种方式都有使用,需要都掌握
3.泛型方法
泛型方法,个人感觉使用应该不多,但是有必要了解一下,因为在jdk文档当中有一些这样的例子。
1 | public <T> T[] fun(T...t){ |
4.通配符
通配符是为了配合泛型类等做参数而使用的,为了防止函数只能对一个具体的参数进行处理而产生的。
常用的 T,E,K,V,?
本质上这些个都是通配符,没啥区别,只不过是编码时的一种约定俗成的东西。比如上述代码中的 T ,我们可以换成 A-Z 之间的任何一个 字母都可以,并不会影响程序的正常运行,但是如果换成其他的字母代替 T ,在可读性上可能会弱一些。通常情况下,T,E,K,V,? 是这样约定的:
- ? 表示不确定的 java 类型
- T (type) 表示具体的一个java类型
- K V (key value) 分别代表java键值中的Key Value
- E (element) 代表Element
? 无界通配符
类型通配符一般是使用?代替具体的类型参数。例如 List 在逻辑上是List,List 等所有List<具体类型实参>的父类。
1 | public static void getData(List<?> data) { |
除了上述的?通配符,还衍生出了如下两个通配符:
?extends:设置泛型上限,参数和方法申明上都可以使用如:
?extends Number,表示只能设置Number或者其子类,例如:Integer、Double,就是说泛型的上限就是Number
1 | class Point<T extends Number >{ |
1 | public void fun(List<? extends Number> list){ |
?super:设置泛型下限,只能设置在参数上如:
?super String,表示只能设置String或者其父类,例如:Object,就是说泛型的下限就是String
1 | public void fun(List<?super Number> list){ |

参考:https://juejin.im/post/6844903917835419661
总结
java泛型以前有所了解但是使用不多,这次系统的复习一下,做个小结。