JavaSE---泛型
概述
Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了“伪泛型”的策略,
(Java在语法上支持泛型,但是在编译阶段会进行所谓的“类型擦除”(Type Erasure),
将所有的泛型表示(尖括号中的内容)都替换为具体的类型(其对应的原生态类型),就像完全没有泛型一样)
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。
也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
引入泛型的意义
适用于多种数据类型执行相同的代码(代码复用)
使用方式
泛型类
自定义泛型类:
public class GenericTest<T> { private T t; /** * 构造器名称还是类名称GenericTest */ public GenericTest(){ } public GenericTest(T t){ t = t; } public static void main(String[] args) { /** * 使用时 类名称<> */ new GenericTest<String>(); } }
不存在泛型类
/** * 不管泛型的实际类型参数是什么,运行时 总是相同的Class */ static void testThree(){ List<String> list =new ArrayList<>(); List<Integer> list1 =new ArrayList<>(); System.out.println(list.getClass()); // class java.util.ArrayList System.out.println(list.getClass() == list1.getClass()); // true }
类型通配符
?;
使用泛型类 时,应该为泛型类传入一个类型实参,但实参类型不明确,可以使用类型通配符;
eg : List<?>
设定类型通配符的上限
有些情况下,不希望 类型实参为所有的类型,只希望是某一类型的父类 extends ;
eg : List<? extends Shape>
设定类型形参的上限
Java不仅运行 类型通配符形参时设定上限、还支持 定义类型形参 时设定上限;
eg : Test<T extends List>
设定类型通配符的下限
eg : <? super Type>
泛型方法
Generic Method;
在声明方法时,定义 一个或多个类型形参;
某些情况下,定义类、接口时未使用类型形参,定义方法时想自定义类型形参;
语法:
修饰符 <T, S> 返回值类型 方法名 (形参列表){}
类型形参
声明 :以尖括号括起来,多个类型形参 以 “,”分隔,位于 修饰符 与 返回值类型 之间;
泛型方法的 类型形参 只能在方法内 使用,可以当做普通类型使用;
使用:
调用泛型方法时,和普通方法一样;
擦除
为了与老的Java代码保持一致,允许 在使用带泛型声明的类 时不指定 类型参数;
如果不指定类型实参,默认该参数为第一个上限类型;
/** * 擦除 */ static void testFour(){ List<String> list = new ArrayList<>(1); list.add("1"); List b = list; // 此时b 的List 只识别 Object }
转换:
/** * 转换 */ static void testFive(){ List<Integer> list = new ArrayList<>(1); list.add(1); List list1 = list; List<String> list2 = list1; // 编译时、运行 正常; 引起 "未经检查的转换" 警告: System.out.println(list2.get(0)); // 运行时 异常: Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String }
类型擦除
简单理解为 将 泛型Java代码 转化为 普通Java代码;
过程:
1、将 所有泛型参数 用顶级父类Object替换 2、移除类型参数