夯实Spring系列|第二十一章:Spring 泛型处理(Generic Resolution)
文章目录
本章说明
本章主要是介绍 Spring 中泛型的一些设计细节,以及一些关键 API 的使用。
1.项目环境
- jdk 1.8
- spring 5.2.2.RELEASE
- github 地址:https://github.com/huajiexiewenfeng/thinking-in-spring
- 本章模块:generic
2.Java 泛型基础
泛型类型
- 泛型类型是在类型上参数化的泛型类或者接口
泛型使用场景
- 编译时强类型检查
- 避免类型强转
- 实现通用算法
泛型类型擦写
泛型被引入到 Java 语言中,以便在编译是提供更严格的类型检查并支持泛型编程。类型擦除确保不会为参数化类型创建新类;因此,泛型不会产生运行时开销。
为了实现泛型,编译器将类型擦除应用于:
- 将泛型类型中的所有类型参数替换为其边界,如果类型参数是无边界的,则将其替换为
Object
。因此,生产的字节码只包含普通类、接口和方法 - 必要时插入类型转换以保持类型安全
- 生成桥接方法时以保留扩展泛型类型中的多态性
2.1 举例说明
集合场景
public interface Collection<E> extends Iterable<E> {
...
boolean addAll(Collection<? extends E> c);
...
1234
<? extends E>
可以保证参数的边界,E 或者 E 的子类,同时也确保的了多态性- E 表示插入元素类型,做一个类型的约束
2.2 代码示例
public class GenericDemo {
public static void main(String[] args) {
// Java 7 Diamond 语法
Collection<String> list = new ArrayList<>();
list.add("Hello");
list.add("World");
// 编译时错误
// list.add(1);
// 通过下面的方式可以欺骗编译器
// 泛型擦写
Collection temp = list;
// 编译通过
temp.add(1);
System.out.println(list);
}
}
123456789101112131415161718
3.Java 5 类型接口
Java 5 类型接口 - java.lang.reflect.Type
派生类或接口 | 说明 |
---|---|
java.lang.Class | Java 类 API,如 java.lang.String |
java.lang.reflect.GenericArrayType | 泛型数组类型 |
java.lang.reflect.ParameterizedType | 泛型参数类型 |
java.lang.reflect.TypeVariable | 泛型类型变量,Collection 中的 E |
java.lang.reflect.WildcardType | 泛型通配类型 |
Java 泛型反射 API
类型 | API |
---|---|
泛型信息(Generics Info) | java.lang.Class#getGenericInfo |
泛型参数(Parameters) | java.lang.reflect.ParameterizedType |
泛型父类(Super Classes) | java.lang.Class#getGenericSuperclass |
泛型接口(Interfaces) | java.lang.Class#getGenericInterfaces |
泛型声明(Generics Declaration) | java.lang.reflect.GenericDeclaration |
API 使用示例
public