《spring设计思想》28-Spring泛型处理-generic

上一节讲到类型转换,有个特别注意的点忘记补充,就是ConverterServiceFactoryBean注册到spring上下文的时候,id一定要命名为"conversionService",否则spring会依赖查找不到。

这一节梳理一下Java/Spring的泛型处理

在jdk5版本中,java引入了泛型的概念,之前的版本是不支持范型的。

java类型的概念,涉及的基本内容有一下几个,

Type->Class->raw type->原始类型->数组类型->集合类型->参数化类型

Type作为java类型的顶级接口,被Class实现,但是Type只有一个getTypeName的接口

public final class Class implements java.io.Serializable,
                              GenericDeclaration,
                              Type,
                              AnnotatedElement {
}

raw type原生类型: 包括int/char/byte/boolean等基本类型.

原始类型: 包括包装类型 Integer/String/Boolean/等和我们自己定义的类型。

数组类型:String[].class等

集合类型:Collection.class等

参数化类型:ArrayList.class等

什么是泛型?

大家都知道java在运行时会有类型擦除的概念,比如我们的List a 在运行时可以手动添加Integer类型,或者String类型的数据:

    public static void main(String[] args) {
        List a = new ArrayList<>();
        a.add("111");
        List b = a;
        b.add(1);
        System.out.println(a.get(1));

    }

系统不会报错,但是在获取的时候会抛出异常,所以在运行时,虚拟机不会校验集合中的数据是否是同一类型,因为集合中的对象都是Object。那么为了保证我们在数据操作是保存的数据类型一致性,我们引入泛型的概念,让集合在声明的时候,指定本次集合数据的类型,保证在编译的时候就能校验数据操作是否正确。

《spring设计思想》28-Spring泛型处理-generic_第1张图片

列表a在声明的时候指定集合参数是String 类型,那么a.add(1)就是非法操作,编译器就会报错。

所以带有等指定类型的数据类型叫《参数化类型》----泛型

泛型作用的地方有三个:泛型类/泛型接口/泛型方法

泛型接口:

《spring设计思想》28-Spring泛型处理-generic_第2张图片

参数化类型中的就是一个参数,可以表示任意类型(原始类型)

该接口定义的接口可以使用T来代表方法的入参和返回类型

泛型类:跟泛型接口差不多

泛型方法:

《spring设计思想》28-Spring泛型处理-generic_第3张图片

泛型方法可单独声明。

Java的反射带有接口描述参数化类型方法:ParameterizedType

        // 参数化类型
        ParameterizedType type = (ParameterizedType) HashMap.class.getGenericSuperclass();
        
        System.out.println(type);
        //真正的 参数类型
        Stream.of(type.getActualTypeArguments()).forEach(System.out::println);

可以输出当前指定类的泛型实际参数。

spring中也有工具类来解析泛型:

1:

GenericTypeResolver

2:

ResolvableType

推荐使用ResolvableType来解析:

public class ResolvableTypeDemo {
    public static void main(String[] args) {
        //展示集合的泛型
        displayCollectionGenericType(StringList.class);
        displayCollectionGenericType(IntegerList.class);

        // 展示bean的泛型
        displayGeneric(StringAndStringMap.class);

        //展示map的泛型
        displayMapGeneric();
    }

    private static void displayMapGeneric() {
        ResolvableType resolvableType = ResolvableType.forClass(StringAndStringMap.class);
        System.out.println(resolvableType.getRawClass());
        System.out.println(resolvableType.asMap().getGeneric(0));
        System.out.println(resolvableType.asMap().getGeneric(1));
    }

    private static void displayGeneric(Class claze) {
        ResolvableType resolvableType = ResolvableType.forClass(claze);
        System.out.println(resolvableType.getRawClass());
        System.out.println(resolvableType.getGeneric(0));
    }

    private static void displayCollectionGenericType(Class claze) {
        ResolvableType resolvableType = ResolvableType.forClass(claze);
        System.out.println(resolvableType.getRawClass());
        System.out.println(resolvableType.asCollection().resolve());
        System.out.println(resolvableType.asCollection().getGeneric(0));
    }
}

spring中的泛型处理还挺多的,但是我现在还没看到,没有啥实例可以借鉴

你可能感兴趣的:(spring,generic,泛型)