子接口有 ParameterizedType, TypeVariable, GenericArrayType, WildcardType, 实现类有Class。...如 Map map 这个 ParameterizedType 返回的是 String 类,Person 类的全限定类名的 Type Array。...如 Map map 这个 ParameterizedType 返回的是 Map 类的全限定类名的 Type Array。...返回的是这个 ParameterizedType 所在的类的 Type (注意当前的 ParameterizedType 必须属于所在类的 member)。解释起来有点别扭,还是直接用代码说明吧。...此时,所有的原始类型都通过字节码文件类Class类进行抽象。Class类的一个具体对象就代表一个指定的原始类型。 泛型出现之后的类型 泛型出现之后,扩充了数据类型。
Class 用来描述类的Class对象。 ParameterizedType 用来描述参数化类型。...parameterizedType = (ParameterizedType) genericSuperclass; Type[] actualTypeArguments = parameterizedType.getActualTypeArguments...那么问题来了如何封装一个工具类? 封装工具类 我们可以借助于抽象类来定义一个获取java.lang.reflect.ParameterizedType的工具类。...ParameterizedType parameterizedType = (ParameterizedType)type; // 获取泛型的具体类型 这里是单泛型 Type...这一招在封装一些通用类库的时候非常有用,比如反序列化工具类。看完了别忘关注码农小胖哥并一键四连哦。
先说结论:通过 Java 反射包的 ParameterizedType 工具获得泛型具体类型。...关键地方来了,调用 getGenericSuperclass 方法,这个方法的作用是:返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type。...然后呢,判断这个 t 是不是 ParameterizedType 接口的实现类。...) { ParameterizedType parameterizedType = (ParameterizedType) type; System.out.println(parameterizedType.getActualTypeArguments...但通过 Class 类的众多反射功能,我们还是能够处理泛型的问题。 我们今天使用反射得到了一个类的泛型,并在父类进行处理,成功的将一个字符串反序列化成一个对象。
此时,所有的原始类型都通过字节码文件类Class类进行抽象。Class类的一个具体对象就代表一个指定的原始类型 泛型出现之后,扩充了数据类型。...**Class —— 反射基石 其意义为:类的抽象,即对“类”做描述:比如类有修饰、字段、方法等属性,有获得该类的所有方法、所有公有方法等方法。...那我们其实就可以通过定义类的方式,在类信息中保留泛型信息,从而在运行时获得这些泛型信息。...) parameterizedType.getActualTypeArguments()[0]; } // 省略具体的操作.... } 说明:Class类有两个"雷同"的方法:...此时,所有的原始类型都通过字节码文件类Class类进行抽象。Class类的一个具体对象就代表一个指定的原始类型。 泛型出现之后,也就扩充了数据类型。
1 JAVA的Type类型体系 先了解下java的Type类型体系(类的类=>类型),Type是所有类型(原生类型-Class、参数化类型-Parameterizedtype、数组类型-GenericArrayType...Type下面又有四个子接口类ParameterizedType、TypeVariable、GenericArrayType、WildcardType List表示泛型,E是TypeVariable...,可以是已知类(Integer、String等),也可以用子类自己的泛型参数指定 泛型被继承时,且指定父类泛型参数,则额外生成的ParameterizedType类型作为子类的父类;如果没有指定父类泛型参数...) // 2 获取在类内部定义的泛型属性,需指定具体泛型参数 // 3 局部代码,可以通过泛型的匿名内部子类(需指定具体泛型参数)获取ParameterizedType类型 public class MainTest...但是泛型类+具体参数转变的ParameterizedType(参数化类型)是不存在继承关系;即Object是String的父类,但是List和List的类型是不同的两个ParameterizedType
{//......} (2)在类里面使用一个泛型类 比如在Java的LinkedList的源码中,有两个成员变量定义如下,分别代表链表的头和尾: transient Node first...; transient Node last; ok,在上面的两种场景中,第一种场景在类和接口上声明的泛型,在运行时反射该类,是没法知道其参数信息的,包括对象本身也不知道它的泛型是什么。...不能通过发射获取泛型类型信息的场景有二个,分别是: (1)类或接口声明的泛型信息 (2)局部变量的泛型信息 获取方法返回值的泛型类型 如下面定义的一个测试类: public class MyClass...){ ParameterizedType parameterizedType=(ParameterizedType) genericsFieldType; Type...){ ParameterizedType parameterizedType=(ParameterizedType)genericType; Type
types (e.g., Map)"); } ParameterizedType parameterizedType = (ParameterizedType...types (e.g., Map)"); } ParameterizedType parameterizedType = (ParameterizedType...,大家对这个类熟悉了吗?...ok,我们来看最后一个类Retrofit类 三、Retrofit (一) 类注释 老规矩先来认识下这个类,首先看这个类的注释 Retrofit adapts a Java interface to...getMethods()返回的是某个类的所有public的方法,包括其继承类的public方法,也包括实现接口的方法。
一般情况下,是不可以直接实例化泛型的,可以通过反射的机制实例化 代码 /** * 获取父类泛型类型 * * @param c 类 * @param...index 父类泛型位置 * @return Type */ public static Type getSuperclassArgumentsActualType(Class...> c, int index) { Type superClass = c.getGenericSuperclass(); return ((ParameterizedType...) { ParameterizedType parameterizedType = (ParameterizedType) type; Type rawType...= parameterizedType.getRawType(); return (Class) rawType; } else if (type instanceof
1 核心接口及类 fastJson 的泛型反序列化场景经常使用到 TypeReference,如下示例: public static void main(String[] args) { List...核心接口,返回泛型类型数组, 该接口可获取父类实际泛型类型,返回的Type数组对象表示该类型的实际类型参数。...null fastjson对其的实现类 ?...一般使用如下 new TypeReference>(){} 创建一个TypeReference的匿名类,在其构造器中拿到泛型对应Type(java.lang.reflect.ParameterizedType...TypeReference的存在是因为java中子类可以获取到父类泛型的真实类型,为便于理解,看一段测试代码 public class TypeReferenceKest { public static
一、泛型的使用和类型擦除 泛型本质上是参数化类型(paramentersized type)的应用,可以声明在类、接口或者方法上。...文件中依次为Class版本、常量池、访问标志、父类信息、字段表、方法表等。类、字段表、方法表等都有属性表,在属性表中有个Signature属性就是用于记录泛型签名信息的。...四、配合反射获取泛型信息 我们定义一个泛型类 open class SuperClass { } class TestClass: SuperClass()...根据上面的分析可以知道从参数化类型信息中就可以得到真实类型 @Test fun testFun() { val clazz = TestClass::class.java //获取类泛型...as ParameterizedType val parameterClass = parameterizedType.actualTypeArguments[0] as Class
,如果父类的方法中需要知道具体子类的Class类型 则可以直接使用Child来使用; 此处的原理就是在子类继承父类的时候 带有泛型 然后子类在创建的时候,会调用父类的构造函数,构造函数中存在this...指的的是子类,然后通过获得父类,再获得父类的泛型 ;通过泛型找到子类类型; 3、原理分析 该实现是通过反射技术实现;下面看具体的分析; 3、1 ParameterizedType 类 ParameterizedType...pType = (ParameterizedType) maps.getClass().getGenericSuperclass();//获得HashMap的父类 System.out.println...Class)的区别 3、2 Type类 Type是java类型信息体系中的顶级接口,其中Class就是Type的一个直接实现类。...ParameterizedType parameterizedType = (ParameterizedType) type; Type[] actualTypeArguments
泛型变量可以在类和方法中进行声明,从上面类图中也可以看出来,java中任何类可以使用Class对象表示,方法可以用Method类表示,类图中可以知,Class类和Method类实现了GenericDeclaration...class对象,通过Class对象可以获取类或者接口中的任何信息,比如:类名、类中声明的泛型信息、类的修饰符、类的父类信息、类的接口信息、类中的任何方法信息、类中任何字段信息等等。...instanceof ParameterizedType) {//@6 ParameterizedType parameterizedType = (ParameterizedType...@4:输出了genericSuperclass变量的类型,注意上面第2行输出:ParameterizedTypeImpl,这个是ParameterizedType接口的一个实现类。...instanceof ParameterizedType) { //@4 ParameterizedType parameterizedType = (ParameterizedType
,如果想根据一个已有的ParameterizedType对象替换其中的参数,上面的方法并不能实现。...实现这个需求最关键的就是要有一个ParameterizedType接口的实现类,有了这个实现类,你想怎么替换都成。...可惜,不论是jdk还是guava的 ParameterizedTypeImpl类都不是public的,所以没办法直接拿来用。所以就只能自己造一个。...完整代码如下(中文注释部分是我增加的方法),代码中用到了guava中的TypeToken工具类实现,只是为了少写些代码。...) { ParameterizedType that = (ParameterizedType) o; if (this == that) {
PS: ExecutorCallbackCall类里面有个变量叫做final retrofit2.Call delegate,而这个retrofit2.Call的具体实现类是retrofit2....通过上述代码我们知道createCallAdapter的内部其实是通过retrofit类中的callAdapter()方法来实现的。...那我们再来看下retrofit类中的callAdapter()方法: public CallAdapter)"); } ParameterizedType parameterizedType = (ParameterizedType...让我们看下ServiceMethod类的toRequest()方法 1.3、ServiceMethod类的toRequest()方法详解 Request toRequest(Object... args
既然Java虚拟机中不存在泛型,那么为什么可以从JDK中的一些类库获取泛型信息?...这是因为类文件(.class)或者说字节码文件本身存储了泛型的信息,相关类库(可以是JDK的类库,也可以是第三方的类库)读取泛型信息的时候可以从字节码文件中提取,例如比较常用的字节码操作类库ASM就可以读取字节码中的信息甚至改造字节码动态生成类...> list; class MyClass{ } 而像下面的忽略泛型参数或者基本数据类型和基本数据类型的包装类都不是ParameterizedType: String name = "throwbale...//获取父类泛型类型数组 Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();...Type[] getBounds():获得该类型变量的上限(上边界),若无显式定义(extends),默认为Object,类型变量的上限可能不止一个,因为可以用&符号限定多个(这其中有且只能有一个为类或抽象类
先说结论:通过 Java 反射包的 ParameterizedType 工具获得泛型具体类型。...关键地方来了,调用 getGenericSuperclass 方法,这个方法的作用是:返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的直接超类的 Type。...然后呢,判断这个 t 是不是 ParameterizedType 接口的实现类。...) { ParameterizedType parameterizedType = (ParameterizedType) type; System.out.println(parameterizedType.getActualTypeArguments...但通过 Class 类的众多反射功能,我们还是能够处理泛型的问题。 我们今天使用反射得到了一个类的泛型,并在父类进行处理,成功的将一个字符串反序列化成一个对象。 很干!必须好看☟
场景示例: 假设我们有一个包含泛型的类,如下所示: public class MyClass { // 类中包含泛型T的相关操作 } 当我们尝试通过反射获取MyClass的泛型信息时,可能会出现...) { ParameterizedType parameterizedType = (ParameterizedType) type; Type...} catch (Exception e) { e.printStackTrace(); } } } 错误分析: 在这个例子中,MyClass类本身并没有父类...,getGenericSuperclass()方法返回的是Object类,因此它不是一个ParameterizedType,导致类型转换异常。...) { ParameterizedType parameterizedType = (ParameterizedType) genericInterface;
(); if (genericSuperclass instanceof ParameterizedType) { System.out.println("父类是一个参数化类型...来解决这一类泛型问题。...我们分析,会发现其实T类似于一个变量,我们可以在使用时可以传入具体的类,比如我们可以这样: SpecialDemo specialDemo...这个接口只有3个实现类(忽略Executable抽象类)。如下: ? 在这里插入图片描述 从这里我们也能看到,我们只能在方法(包括普通方法跟构造方法)以及类上申明泛型。...基于这种情况,Spring开发了一个ResolvableType类,这个类对整个Type体系做了系统的封装。
这里只是以泛型方法来做个说明,其实泛型类,泛型返回值都是类似的,兄弟们可以自己动手试试看。...由于Java的泛型擦除,在运行时,只有一个List类,那么相对于C#的基于膨胀的泛型实现,Java类的数量相对较少,方法区占用的内存就会小一点,也算是一个额外的小优点吧。...) { ParameterizedType parameterizedType = (ParameterizedType) superType; Type[] actualTypes = parameterizedType.getActualTypeArguments...) { ParameterizedType parameterizedType = (ParameterizedType) returnType;...) { ParameterizedType parameterizedType = (ParameterizedType) superType; Type
领取专属 10元无门槛券
手把手带您无忧上云