泛型
泛型就是允许在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返
回值及参数类型。
泛型的作用:一种安全机制,它可以帮助我们建立类型安全的集合
其通过<>声明给编译器,只能往内部存储某种数据的元素。
<>用于接收具体引用数据类型的参数范围
泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。
泛型的擦除:
类型擦除指的是在Java泛型程序运行过程中出现的类型被转换为Object或者其限定类型的现象。
例如:
Class<?> c1 = new ArrayList<String>().getClass();
Class<?> c2 = new ArrayList<Integer>().getClass();
System.out.println(c1 == c2); // true
虽然泛型类的参数不同,但是结果却是TRUE。
这是因为在泛型代码内部,无法获得任何有关泛型参数类型的信息。
所有的泛型类型在运行过程中都会被擦除。这意味着当你在使用泛型时,你唯一知道的是你在使用一个对象。因此List
泛型的补偿:
在运行时,需要通过获取元素的类型进行转换工作,我们无需使用者再强制转换。
因为泛型会通过getClass取到集合内部数据类型,然后帮我们进行强转
泛型的约定规范
- 当一个泛型类声明了定义泛型参数时,我们就需要往里面传所需要的类型参数
如果指定,默认是object类型
泛型类
在类/接口上声明的泛型,在本类或本接口中即代表某种类型,可以作为非静态 属性的类型、参数类型、返回值类型。
但在静态方法 中不能使用类的泛型。
根据工具类写实现类时,就可以往泛型参数里面传入想要实例化的类。还可以省略强转
泛型方法
泛型方法一般用于泛指,就是说 设置了一个通用的返回值类型
- 泛型方法跟指定Object类型的区别:引用了Object数据类型,就只能使用Object定义的方法
- 而泛型,可以实现多参数传入(实现多个类型的方法)。
注:泛型类和泛型方法直接没有关系 ,泛型方法仅仅是指在方法中出现了泛型的结构,泛型参数与类的泛型参数没任何关系。
//泛型方法,可以声明为静态的。
public static <E> List<E> copyFromArrayToList(E[] arr){
ArrayList<E> list = new ArrayList<>();
for(E e : arr){
list.add(e);
}
return list;
}
}
泛型的通配符“?”
当不明确想要声明的引用数据类型时,就可以使用通配符 ?
使得所有的引用数据类型都能匹配 (或者说,引用的数据类型都是object)
泛型限定:
泛型限定是用于泛型扩展使用的。其中包含了多态的思想。
限定继承
使用 <? extends E > 来限定通配符的范围,表示只接收E类型或者E的子类型对象。
举例:
由于定义了T泛型的变量,但由于我们需要进行比较,所以,需要该变量类型实现Comparable接口,但是,我们却无法对类型做出任何继承操作。
所以,此时我们应该进行泛型限定。
限定父类
使用 <? super E > 来限定通配符的范围,表示只接收E类型或者E的父类类型对象
可以同时进行多种限定
例如: T extend Comparable & Serializable