Java|阿里开源5天被网友疯狂转载的Java泛型详解手册,带你一文通关


Java|阿里开源5天被网友疯狂转载的Java泛型详解手册,带你一文通关
文章图片
Java|阿里开源5天被网友疯狂转载的Java泛型详解手册,带你一文通关
文章图片
Java|阿里开源5天被网友疯狂转载的Java泛型详解手册,带你一文通关
文章图片
Java|阿里开源5天被网友疯狂转载的Java泛型详解手册,带你一文通关
文章图片
Java|阿里开源5天被网友疯狂转载的Java泛型详解手册,带你一文通关
文章图片
Java|阿里开源5天被网友疯狂转载的Java泛型详解手册,带你一文通关
文章图片
Java|阿里开源5天被网友疯狂转载的Java泛型详解手册,带你一文通关
文章图片
Hello , 今天给各位童鞋们分享的是Java泛型 , 赶紧拿出小本子记下来吧
java泛型为了让集合记住其元素的数据类型而不是都作为object处理 , 参数化类型 , aka , 泛型从java5开始引进 。
泛型类、泛型接口、泛型方法、类型通配符、逆变、协变等!
java7以前构造器后面还是需要在尖括号后面加上类型的 , 7之后不需要了 , 支持菱形语法 。 9开始可以在创建匿名内部类时使用菱形语法 。
使用var声明变量时 , 程序无法使用菱形语法 。
泛型定义所谓泛型就是允许在定义类、接口、方法时使用类型形参(泛型) , 这个类型参数将在声明变量、创建对象、调用方法时动态地指定(类型实参) 。
示例:
对于自定义泛型声明类的构造器 , 构造器还是原来的类名 , 不加菱形 。
从泛型类派生子类当使用这些泛型声明的接口或父类时 , 不能再包含泛型形参 。 下面是错的
如:
public class Menu extends MenuReverseController<Y>{
<泛型参数>应该删去或者传入具体的类型来代替Y 。 以下两种方式均可 。
public class Menu extends MenuReverseController<String>{
//原始类型//原始类型会被当做Object类型
public class Menu extends MenuReverseController{
并不存在泛型类ArrayList<String>不是新类;
输出为true;因此都会被当做同一个类处理 , 因此关于类的声明(静态方法、静态初始化块或者静态变量的声明和初始化中不允许使用泛型形参 。 )
由于系统并不会真正生成泛型类 , 所以instanceof运算符后不能使用泛型类 。
类型通配符List是个泛型接口 , 使用时要传入泛型实参 , 但是List<String>不是List<Object>的子类 , java泛型的设计原则是 , 只要代码在编译时候没有出现警告 , 就不会遇到运行时ClassCastException异常 。
加入Foo是Bar的一个子类型(子类或者子接口) , 那么Foo[
依然是Bar[
的子类型 , 但G<Foo>不是G<Bar>的子类型 。 Foo[
自动向上转型为Bar[
的方式称为型变 。 数组支持型变 , 集合不支持 。
使用类型通配符
为了表示各种泛型List的父类 , 可以使用类型通配符 , 即问号?
将一个问号作为实参进行传递 , 但是它仅仅表示它是各种泛型的父类 , 并不能把元素加入其中 。 只可以加入null(所有引用类型的实例) 。
另一方面 , 程序可以返回List<?>指定索引处的元素 , 返回值肯定是一个Object 。 因此把返回值赋值给一个Object类型的变量 。
设定类型通配符上限
有时候会想要设定某一类泛型List的父类 。 List<? extend Shape>上限为Shape , 这个可以表示Listxxx的父类 , 因为无法确定这个受限制的通配符的具体类型 , 所以不能把shape对象或其子类对象加入到这个泛型集合中 。 主要是程序无法确定类型是哪个!
这种指定通配符上限的集合只能从集合中取元素(取出的元素总是上限的类型或其子类) , 不能向集合中添加元素(因为编译器无法确定集合元素实际是哪种子类型) 。
这种型变方式称为“协变”!
协变泛型只能调用泛型类型作为返回值类型的方法(编译器会将该方法返回值当成通配符上限的类型);而不能调用泛型类型作为参数的方法 。 口诀是只出不进 。 没有指定通配符上限 , 相当于上限为Object 。
设定类型通配符下限
跟上面的上限相反 , 用A<? super Shape> 。
程序可将Shape的父类泛型赋值过去 。 这种型变方式称为逆变!