java Type 及其子类介绍

java Type 及其子类介绍

Type 是java反射机制中提供的一个接口,用来表示java中的所有类型的接口,定义如下:

package java.lang.reflect;
public interface Type {
    default String getTypeName() {
        return this.toString();
    }
}

Typejava编程语言中所有类型的通用超级接口,包括原始类型Class,参数化类型,数组类型,类型变量和基本类型。其子类有:

原始类型Class

Class类的实例用来表示java中所有的类, 可以用Class.forName加载一个类,也可以获取到通过一个类的Class对象获取到该类的所有属性,方法,继承的类和接口。

Class<?> clz = MethodHandle.class;
Constructor<?>[] cons = clz.getConstructors();
Method[] methods = clz.getMethods();
Field[] fields = clz.getFields();

泛型数组类型 GenericArrayType

接口GenericArrayType代表泛型数组类型,泛型数组指数组中元素是参数类型或者类型变量。

class GenericArrayTypeTest<T> {
    List<Integer>[] field1;
    T[] field2;
}
public static void genericArrayTest() {
    Class<?> clazz = GenericArrayTypeTest.class;
    try {
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            Type type = field.getGenericType();
            // 输出 java.util.List<java.lang.Integer>[] / T[]
            System.out.println(type);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

参数化类型ParameterizedType

接口ParameterizedType表示参数化类型,例如Collection<String>;他在反射方法第一次使用参数化类型时被创建,当一个ParameterizedType实例被创建时,将递归解析类型声明中的所有类型参数。

class ParameterizedTypeTest {
    public Map<String, Integer> failed1;
    public List<String> failed2;
}
public class TypeReview {
    public static void main(String[] args) {
        Class<?> clz = ParameterizedTypeTest.class;
        Field[] fields = clz.getFields();
        for (Field field : fields) {
            Type ftype = field.getGenericType();
            if (ftype instanceof ParameterizedType) {
                ParameterizedType parameterizedType = (ParameterizedType) ftype;
                // 获取参数类型名称,Map<String, Integer>和 List<String>
                System.out.println(parameterizedType.getTypeName());
                // null
                System.out.println(parameterizedType.getOwnerType());
                // 获取原始类型,输出为interface java.util.Map/List
                System.out.println(parameterizedType.getRawType());
                // 获取实际类型参数
                for (Type ptype : parameterizedType.getActualTypeArguments()) {
                    System.out.println(ptype.getTypeName());
                }
            }
        }
    }

}

class ParameterizedTypeTest {

    public Map<String, Integer> failed1;
    public List<String> failed2;

}

类型变量TypeVariable

TypeVariable代表在Java类,构造方法和方法中声明的类型变量:

class TypeVariableTest<T> {
    public <E> TypeVariableTest() {

    }
    public <F> void method1() {

    }
}
public static void main(String[] args) {
    Class<TypeVariableTest> clazz = TypeVariableTest.class;
    TypeVariable<?>[] typeVariable = clazz.getTypeParameters();
    for (TypeVariable<?> variable : typeVariable) {
        System.out.println(variable.getGenericDeclaration());
        System.out.println(variable.getName());
        System.out.println(variable.getTypeName());
    }
    try {
        Method method = clazz.getMethod("method1");
        TypeVariable[] typeVariables = method.getTypeParameters();
        for (TypeVariable variable : typeVariables) {
            System.out.println(variable.getTypeName());
        }
        Constructor<?> constructor = clazz.getConstructor();
        typeVariables = constructor.getTypeParameters();
        for (TypeVariable variable : typeVariables) {
            System.out.println(variable.getTypeName());
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

WildcardType 通配符类型

表示一个通配符表达式,如?? extends Collection? super List。该接口提供的方法有:

// 返回上界
Type[] getUpperBounds();
// 返回下界
Type[] getLowerBounds();

Mybatis源码中Type使用示例

示例1: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();
    // 
    } 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;
}

Class对象中getField(s)/getDeclaredField(s)区别:

getField(s):

用来获取Class对象所表示类中的公开方法,getMethod(String name , Class<?>... parameterTypes)获取指定名称和参数类型的方法的Method对象,getMethods获取所有公开方法;

getDeclaredField(s)

获取Class对象所表示类中所有声明的方法,参数和返回类型同getMethod(s)

getMethod(s)/getDeclaredMethod(s)getConstructor(s)/getDeclaredConstructor(s)用法与之相似

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值