原文网址:Java反射系列--Type接口及其子接口_IT利刃出鞘的博客-CSDN博客

简介

说明

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--反射--使用/应用/实例_IT利刃出鞘的博客-CSDN博客

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

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> ,则为 ListType getRawType();//如果是内部类,获取拥有内部类的外部类。例如:Map.Entry<K,V>,则为MapType 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());// 父类。本处都是NullSystem.out.println("ownerType: " + parameterizedType.getOwnerType());// 原始类型。输出:interface java.util.List/MapSystem.out.println("rawType:   " + parameterizedType.getRawType());// 参数实际类型。输出:T和java.lang.String/Integerfor (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>,则为NumberType[] getUpperBounds();// 获取下边界。例如:List<? super String>, 则为StringType[] 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;
}

其他网址

Java Type类及其子类用途 - 简书
java Type 及其子类介绍_qq_37718687的博客-CSDN博客

Java反射系列--Type接口及其子接口相关推荐

  1. 通过Java反射获取对象上的注解,java反射注解妙用-获取所有接口说明

    原标题:java反射注解妙用-获取所有接口说明 转载请注明出处:https://www.cnblogs.com/wenjunwei/p/10293490.html 前言 最近在做项目权限,使用shir ...

  2. Java 反射系列 —— 学习笔记

    Java 反射系列 1. 类成员 为了更好的描述,我们做个约定个通配符 XXXX, 如果是成员变量就代表 Field, 如果是类方法就代表 Method, 如果是构造器就代表 Constructor. ...

  3. JavaSE入门学习34:Java集合框架之Collection接口、子接口及其实现类

    一Collection接口 Collection接口定义了存取一组对象的方法,其子接口Set.List和Queen分别定义了存储方式. 使用Collection接口需要注意: 1Collection接 ...

  4. Spring Data JPA 自定义Repository接口与子接口

    上篇文章介绍了 Repository接口的使用(Spring Data JPA介绍与Spring的整合),接下来重点掌握 Repository的CrudRepository子接口下的子接口. 在dao ...

  5. Collection集合接口及其子接口、实现类

    1. Collection 接口简介 2. Collection的子接口 2.1 List接口 List接口的实现类 ① ArrayList ② Vector ③ Stack ④ LinkedList ...

  6. Java 集合系列(三)Collection 接口

    图片来自网络 public interface Collection<E> extends Iterable<E> 复制代码 前面我们刚刚总结过 Iterable 接口拥有遍历 ...

  7. JAVA反射系列之Field,java.lang.reflect.Field使用获取方法。

    2019独角兽企业重金招聘Python工程师标准>>> 首先必须明一点 Field类主要是用来辅助获取和操作类的属性的! 1.怎么通过反射获取类的属性 先来看JDK提供的方法有如下几 ...

  8. JAVA反射系列之Method,java.lang.reflect.Method的使用

    摘要: ava.lang.reflect.Method的基本使用. 最近写项目,用反射的比较多,写一个总结,以便查阅. Method是反射最基本的一个类. 直接上代码: [java] view pla ...

  9. JAVA反射系列之Method,java.lang.reflect.Method的使用。

    2019独角兽企业重金招聘Python工程师标准>>> 最近写项目,用反射的比较多,写一个总结,以便查阅. Method是反射最基本的一个类. 直接上代码: /*** @ClassN ...

最新文章

  1. 组织可以最大限度提高数据中心性能的五个步骤
  2. 信息学奥赛一本通(1087:级数求和)
  3. 【Java】@transient代表着什么
  4. 福利 | 闷骚的程序员是如何讲冷笑话的?
  5. VC++控件加载BMP图片(静态和动态方式)
  6. 拦截导弹 (最长上升子序列LIS)
  7. Redis学习笔记~Redis并发锁机制
  8. php 时间 拼接,PHP关于时间的时段的重合、 整合的方法
  9. 全志A33 Android4.4 RTL8723DS WIFI/BT驱动调试
  10. java 移位运算符
  11. 调用jad生成器生成相应的.jad文件
  12. 统计计量丨统计学公开课大盘点(附下载)
  13. 平均数 中位数 四分位数 方差 标准差
  14. 关于nmap和traceroute在虚拟机里使用的问题
  15. ps2模拟器pc版_如何在Windows PC上使用PS3控制器
  16. 计算机在职研究生是学历教育吗,计算机在职研究生有学籍吗
  17. 人脸识别客户端应用程序_如何在应用程序中使用功能识别设置人脸检测
  18. android获取apk名称_apk是什么文件
  19. 计算机房的正常温度和湿度,各类机房的温湿度标准参考
  20. 你所需要的java基础提升篇大总结

热门文章

  1. 关于采集插件的一些详细知识
  2. 解读LM79测试项目及LM80的区别
  3. COGS-2049 疯狂动物城
  4. OpenJ_Bailian - 2943小白鼠排队
  5. 2021-2022-2-第7次单元练习后记
  6. 使用docker安装mysql数据库(超简单)
  7. Mini RTK | 小巧精致、好测量
  8. 数学证明到底是什么?
  9. 人机混合智能的瓶颈——休谟之问
  10. 如何在生产环境使用devtools?