所有分类
  • 所有分类
  • 未分类

Java反射系列–Type接口及其子接口

简介

说明

Type 是java反射机制中提供的一个接口,用来表示java中的所有类型的接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。(这段话是Type源码的注释中写的)。

  • 原始类型:一般意义上的java类,由class类实现
  • 参数化类型:ParameterizedType接口的实现类
  • 数组类型:GenericArrayType接口的实现类
  • 类型变量:TypeVariable接口的实现类
  • 基本类型:int,float等java基本类型。(其实也是class)

Type类几乎在各种框架中都能看到,尤其是涉及代理,反射的地方。理解好Type类也会对今后框架封装、源码解读有很大好处。

Type接口源码

package java.lang.reflect;

/**
 * Type is the common superinterface for all types in the Java
 * programming language. These include raw types, parameterized types,
 * array types, type variables and primitive types.
 *
 * @since 1.5
 */
public interface Type {
    /**
     * Returns a string describing this type, including information
     * about any type parameters.
     *
     * @implSpec The default implementation calls {@code toString}.
     *
     * @return a string describing this type
     * @since 1.8
     */
    default String getTypeName() {
        return toString();
    }
}

Type的子接口/子类

Type的子接口/子类是这样的:

实例

下边我只用字段进行示例。方法、类都是一样的用法。

Class

Class的方法实在太多了,毕竟它包含了类的所有信息。详细可见这里:Java反射-反射的应用 – 自学精灵

本处只做一个简单的示例。

package com.example.a;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

class ClassTest{
    private String userName;

    public void sayHello() {
        System.out.println("Hello");
    }
}

public class Demo {
    public static void main(String[] args) {
        Field[] declaredFields = ClassTest.class.getDeclaredFields();
        Method[] declaredMethods = ClassTest.class.getDeclaredMethods();

        for (Field declaredField : declaredFields) {
            System.out.println(declaredField.getName());
        }

        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod.getName());
        }
    }
}

ParameterizedType

参数化类型,即带泛型的类型;例如:List<T>、Map<K,V>。

源码

public interface ParameterizedType extends Type {
    //获取参数化类型参数。例如:Map<K,V>,则为K/V数组;
    Type[] getActualTypeArguments();
    
    //获取原始类型,泛型类型。例如:List<T> ,则为 List
    Type getRawType();
    
    //如果是内部类,获取拥有内部类的外部类。例如:Map.Entry<K,V>,则为Map
    Type getOwnerType();
}

实例

package com.example.a;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

class ParameterizedTypeTest<T> {
    private List<T> tList;
    private Map<String, Integer> stringIntegerMap;
}

public class Demo {
    public static void main(String[] args) {
        Field[] declaredFields = ParameterizedTypeTest.class.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            // 获得字段的类型
            Type type = declaredField.getGenericType();
            if (type instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) type;
                // 参数类型名。输出:List<T> 和 Map<String,Integer>
                System.out.println("typeName:  " + parameterizedType.getTypeName());
                // 父类。本处都是Null
                System.out.println("ownerType: " + parameterizedType.getOwnerType());
                // 原始类型。输出:interface java.util.List/Map
                System.out.println("rawType:   " + parameterizedType.getRawType());
                // 参数实际类型。输出:T和java.lang.String/Integer
                for (Type arguments : parameterizedType.getActualTypeArguments()) {
                    System.out.println(arguments.getTypeName());
                }
            }
            System.out.println("----------------------------------");
        }
    }
}

运行结果

typeName:  java.util.List<T>
ownerType: null
rawType:   interface java.util.List
T
----------------------------------
typeName:  java.util.Map<java.lang.String, java.lang.Integer>
ownerType: null
rawType:   interface java.util.Map
java.lang.String
java.lang.Integer
----------------------------------

TypeVariable

类型变量,即泛型中的变量;例如:T、K、V等变量,可以表示任何类;

TypeVariable代表着泛型中的变量,而ParameterizedType则代表整个泛型。

源码

public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
    //获得该类型变量的上限,也就是泛型中extend右边的值;
    //  例如: List<T extends Number> ,Number就是类型变量T的上限;
    Type[] getBounds();

    //获取声明该类型变量实体
    D getGenericDeclaration();

    String getName();

    AnnotatedType[] getAnnotatedBounds();
}

实例

package com.example.a;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.List;
import java.util.Map;

class TypeVariableTest<T> {
    private List<Integer> integerList;
    private Map<String, T> stringTMap;
}

public class Demo {
    public static void main(String[] args) {
        Class<TypeVariableTest> clazz = TypeVariableTest.class;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Type type = declaredField.getGenericType();
            if (type instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType)type;
                for (Type type1 : parameterizedType.getActualTypeArguments()) {
                    if (type1 instanceof TypeVariable) {
                        TypeVariable typeVariable = (TypeVariable) type1;
                        System.out.println("字段名:            " + declaredField.getName());
                        System.out.println("typeName:           " + typeVariable.getTypeName());
                        System.out.println("genericDeclaration: " +
                                typeVariable.getGenericDeclaration());
                    }
                }
            }
        }
    }
}

执行结果

字段名:            stringTMap
typeName:           T
genericDeclaration: class com.example.a.TypeVariableTest

可以发现,经过代码的过滤后,只获取到了T。

GenericArrayType

简介

泛型数组类型,用来描述ParameterizedType、TypeVariable类型的数组;例如:List<T>[] 、T[]、List<Integer>[]等。不包含String[]、int[]这种。

源码

public interface GenericArrayType extends Type {
    //可以获取到数组前面的类型。例如:List<String>[]为List<String>
    Type getGenericComponentType();
}

实例

package com.example.a;

import java.lang.reflect.*;
import java.util.List;

class TypeVariableTest<T> {
    private T[] ts;
    private Integer[] integers;
    private List<Integer>[] integerList;
    private List<T>[] tLists;
}

public class Demo {
    public static void main(String[] args) {
        Class<TypeVariableTest> clazz = TypeVariableTest.class;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Type type = declaredField.getGenericType();
            if (type instanceof GenericArrayType) {
                GenericArrayType genericArrayType = (GenericArrayType)type;
                System.out.println("字段名:              " + declaredField.getName());
                System.out.println("typeName:             " +
                        genericArrayType.getTypeName());
                System.out.println("genericComponentType: " +
                        genericArrayType.getGenericComponentType());
            }
            System.out.println("------------------------------------------");
        }
    }
}

执行结果

字段名:              ts
typeName:             T[]
genericComponentType: T
------------------------------------------
------------------------------------------
字段名:              integerList
typeName:             java.util.List<java.lang.Integer>[]
genericComponentType: java.util.List<java.lang.Integer>
------------------------------------------
字段名:              tLists
typeName:             java.util.List<T>[]
genericComponentType: java.util.List<T>
------------------------------------------

 可见:Integer[]这种不属于GenericArrayType

WildType

简介

泛型表达式(通配符表达式)。例如:? extend Number、? super Integer。

WildcardType虽然是Type的子接口,但却不是Java类型中的一种。

源码

public interface WildcardType extends Type {
    // 获取上边界。例如:List<? extends Number>,则为Number
    Type[] getUpperBounds();

    // 获取下边界。例如:List<? super String>, 则为String
    Type[] getLowerBounds();
}

实例 

package com.example.a;

import java.lang.reflect.*;
import java.util.Arrays;
import java.util.List;

class TypeVariableTest {
    private List<? extends Integer> integerList;
}

public class Demo {
    public static void main(String[] args) {
        Class<TypeVariableTest> clazz = TypeVariableTest.class;
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Type type = declaredField.getGenericType();
            if (type instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) type;
                Type[] typeArguments = parameterizedType.getActualTypeArguments();
                System.out.println("字段名:     " + declaredField.getName());
                for (Type type1 : typeArguments) {
                    if (type1 instanceof WildcardType) {
                        WildcardType wildcardType = (WildcardType) type1;
                        System.out.println("typeName:    " + wildcardType.getTypeName());
                        System.out.println("upperBounds: " +
                                Arrays.toString(wildcardType.getUpperBounds()));
                    }
                }
            }
        }
    }
}

执行结果

字段名:     integerList
typeName:    ? extends java.lang.Integer
upperBounds: [class java.lang.Integer]

框架对Type的应用

Mybatis

org.apache.ibatis.reflection.Reflector中的typeClass方法将Type类型对象转换为Class对象。

private Class<?> typeToClass(Type src) {
    Class<?> result = null;
    // 如果src是Class类型的实例则直接进行强制类型转换
    if (src instanceof Class) {
        result = (Class<?>) src;
    // 如果src是参数类型则获取其原始类型Class对象;
    } else if (src instanceof ParameterizedType) {
        result = (Class<?>) ((ParameterizedType) src).getRawType();
    // 如果src是数组泛型类型,则分情况处理
    } else if (src instanceof GenericArrayType) {
        Type componentType = ((GenericArrayType) src).getGenericComponentType();
        if (componentType instanceof Class) {
            result = Array.newInstance((Class<?>) componentType, 0).getClass();
        } else {
            Class<?> componentClass = typeToClass(componentType);
            result = Array.newInstance(componentClass, 0).getClass();
        }
    }
    if (result == null) {
        result = Object.class;
    }
    return result;
}
0

评论0

请先

显示验证码
没有账号?注册  忘记密码?

社交账号快速登录