Spring 泛型处理

Java 泛型基础

• 泛型类型

  • 泛型类型是在类型上参数化的泛型类或接口

• 泛型使用场景

  • 编译时强类型检查
  • 避免类型强转
  • 实现通用算法

Java 泛型基础

泛型类型擦写

泛型被引入到 Java 语言中,以便在编译时提供更严格的类型检查并支持泛型编程。类型擦除确保不会为参数化类型创建新类;因此,泛型不会产生运行时开销。为了实现泛型,编译器将类型擦除应用于:
• 将泛型类型中的所有类型参数替换为其边界,如果类型参数是无边界的,则将其替换为
“Object”。因此,生成的字节码只包含普通类、接口和方法。
• 必要时插入类型转换以保持类型安全。
• 生成桥方法以保留扩展泛型类型中的多态性。

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);
    }
}

Java 5 类型接口

• Java 5 类型接口 - java.lang.reflect.Type

派生类或接口说明
java.lang.ClassJava 类 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

Spring 泛型类型辅助类

核心 API - org.springframework.core.GenericTypeResolver
• 版本支持:[2.5.2 , )
• 处理类型相关(Type)相关方法

  • resolveReturnType
  • resolveType

• 处理泛型参数类型(ParameterizedType)相关方法

  • resolveReturnTypeArgument
  • resolveTypeArgument
  • resolveTypeArguments

• 处理泛型类型变量(TypeVariable)相关方法

  • getTypeVariableMap
class StringList extends ArrayList<String> { // 泛型参数具体化(字节码有记录)
}

/**
 * {@link GenericTypeResolver} 示例
 */
public class GenericTypeResolverDemo {

    public static void main(String[] args) throws NoSuchMethodException {

        // String 是 Comparable<String> 具体化
        displayReturnTypeGenericInfo(GenericTypeResolverDemo.class, Comparable.class, "getString");

        // ArrayList<Object> 是 List 泛型参数类型的具体化
        displayReturnTypeGenericInfo(GenericTypeResolverDemo.class, List.class, "getList");

        // StringList 也是 List 泛型参数类型的具体化
        displayReturnTypeGenericInfo(GenericTypeResolverDemo.class, List.class, "getStringList");

        // 具备 ParameterizedType 返回,否则 null

        // TypeVariable
        Map<TypeVariable, Type> typeVariableMap = GenericTypeResolver.getTypeVariableMap(StringList.class);
        System.out.println(typeVariableMap);
    }


    public static StringList getStringList() {
        return null;
    }

    public static ArrayList<Object> getList() { // 泛型参数类型具体化
        return null;
    }

    public static String getString() {
        return null;
    }

    private static void displayReturnTypeGenericInfo(Class<?> containingClass, Class<?> genericIfc, String methodName, Class... argumentTypes) throws NoSuchMethodException {
        Method method = containingClass.getMethod(methodName, argumentTypes);

        // 声明类 GenericTypeResolverDemo.class
        Class<?> returnType = resolveReturnType(method, containingClass);

        // 常规类作为方法返回值
        System.out.printf("GenericTypeResolver.resolveReturnType(%s,%s) = %s\n", methodName, containingClass.getSimpleName(), returnType);
        // 常规类型不具备泛型参数类型 List<E>
        Class<?> returnTypeArgument = resolveReturnTypeArgument(method, genericIfc);
        System.out.printf("GenericTypeResolver.resolveReturnTypeArgument(%s,%s) = %s\n", methodName, containingClass.getSimpleName(), returnTypeArgument);

    }

}

在这里插入图片描述

Spring 泛型集合类型辅助类

核心 API - org.springframework.core.GenericCollectionTypeResolver
• 版本支持:[2.0 , 4.3]
• 替换实现:org.springframework.core.ResolvableType
• 处理 Collection 相关

  • getCollection*Type

• 处理 Map 相关

  • getMapKey*Type
  • getMapValue*Type
/**
 * {@link GenericCollectionTypeResolver} 示例
 */
public class GenericCollectionTypeResolverDemo {

    private static StringList stringList;

    private static List<String> strings;

    public static void main(String[] args) throws Exception {

        // StringList extends ArrayList<String> 具体化
        // getCollectionType 返回具体化泛型参数类型集合的成员类型 = String
        System.out.println(GenericCollectionTypeResolver.getCollectionType(StringList.class));

        System.out.println(GenericCollectionTypeResolver.getCollectionType(ArrayList.class));

        // 获取字段
        Field field = GenericCollectionTypeResolverDemo.class.getDeclaredField("stringList");
        System.out.println(GenericCollectionTypeResolver.getCollectionFieldType(field));

        field = GenericCollectionTypeResolverDemo.class.getDeclaredField("strings");
        System.out.println(GenericCollectionTypeResolver.getCollectionFieldType(field));
    }
}

在这里插入图片描述

Spring 方法参数封装

核心 API - org.springframework.core.MethodParameter

• 起始版本:[2.0 , )

• 元信息

  • 关联的方法 - Method
  • 关联的构造器 - Constructor
  • 构造器或方法参数索引 - parameterIndex
  • 构造器或方法参数类型 - parameterType
  • 构造器或方法参数泛型类型 - genericParameterType
  • 构造器或方法参数参数名称 - parameterName
  • 所在的类 - containingClass

Spring 4.0 泛型优化实现 - ResolvableType

核心 API - org.springframework.core.ResolvableType

• 起始版本:[4.0 , )
• 扮演角色:GenericTypeResolver 和 GenericCollectionTypeResolver 替代者
• 工厂方法:for* 方法
• 转换方法:as* 方法
• 处理方法:resolve* 方法

/**
 * {@link ResolvableType} Demo
 */
public class ResolvableTypeDemo {

    public static void main(String[] args) {
        // 工厂创建
        // StringList <- ArrayList <- AbstractList <- List <- Collection
        ResolvableType resolvableType = ResolvableType.forClass(StringList.class);

        resolvableType.getSuperType(); // ArrayList
        resolvableType.getSuperType().getSuperType(); // AbstractList

        System.out.println(resolvableType.asCollection().resolve()); // 获取 Raw Type
        System.out.println(resolvableType.asCollection().resolveGeneric(0)); // 获取泛型参数类型
        
    }
}

在这里插入图片描述

ResolvableType 的局限性

• 局限一:ResolvableType 无法处理泛型擦写
• 局限二:ResolvableType 无法处理非具体化的 ParameterizedType

面试题

Java 泛型擦写发生在编译时还是运行时?
答:运行时

请介绍 Java 5 Type 类型的派生类或接口?
答:
• java.lang.Class
• java.lang.reflect.GenericArrayType
• java.lang.reflect.ParameterizedType
• java.lang.reflect.TypeVariable
• java.lang.reflect.WildcardType

请说明 ResolvableType 的设计优势?
答:
• 简化 Java 5 Type API 开发,屏蔽复杂 API 的运用,如 ParameterizedType
• 不变性设计(Immutability)
• Fluent API 设计(Builder 模式),链式(流式)编程

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值