Loading... Java的泛型是假泛型,即只在编译期有效,在编译过程中会被“擦除”,也就是说,在运行期,JVM是无法推断泛型所代表的具体类型的,但这并不意味着我们无法获取编译好的Class的泛型信息。事实上,从JDK 1.5开始,Class的字节码中类、方法表、字段表的Signature属性会记录有关泛型的信息,我们可以通过相关反射API获取。 ### 测试环境 ``` Windows 10 Oracle JDK 8u241 ``` ### 相关知识 下面先介绍几个使用到的类和方法。 #### Type 接口 根据文档的描述 > 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." 翻译过来就是 > Type 是 Java 语言中所有类型的接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。 具体来说 Class 类实现了这个接口,在Java SE API中,GenericArrayType, ParameterizedType, TypeVariable, WildcardType 是 Type 的子接口,因为 Class 是不包含参数化对象的泛型信息,所以就有了后面的几个接口,下面以含参字段为例我们一一介绍。 #### Field.getGenericType() 返回一个 Type 对象,它表示此 Field 对象所表示字段的声明类型。 如果类型不含参数,会直接返回 Class, 如果类型包含参数,那么返回包含源码中泛型的 Type。具体见以下例子。 #### GenericArrayType 若字段是泛型数组。 ```Java public class GenericArray<T> { public T[] array; public static void main(String[] args) throws Exception { Field field = GenericArray.class.getField("array"); GenericArrayType type = (GenericArrayType) field.getGenericType(); // T[]; Type component = type.getGenericComponentType(); // T } } ``` #### ParameterizedType 若字段的参数无通配符"?"。 ```Java public class Parameterized { public Map<String, Object> map; public static void main(String[] args) throws Exception { Field field = Parameterized.class.getField("map"); ParameterizedType type = (ParameterizedType) field.getGenericType(); Type rawType = type.getRawType(); // Map Type key = type.getActualTypeArguments()[0]; // String Type value = type.getActualTypeArguments()[1]; // Object } } ``` #### TypeVariable 若字段本身类型是参数。 ```Java public class Variable<T extends Number> { public T number; public static void main(String[] args) throws Exception { Field field = Variable.class.getField("number"); TypeVariable<?> type = (TypeVariable<?>) field.getGenericType(); // Number Type[] bounds = type.getBounds(); GenericDeclaration declare = type.getGenericDeclaration(); //Variable } } ``` #### WildCardType 若字段参数包含通配符“?”。 ```Java public class Wildcard { public Function<? super Number, ? extends Number> func; public static void main(String[] args) throws Exception { Field field = Wildcard.class.getField("func"); ParameterizedType type = (ParameterizedType) field.getGenericType(); WildcardType in = (WildcardType) type.getActualTypeArguments()[0]; WildcardType out = (WildcardType) type.getActualTypeArguments()[0]; in.getLowerBounds(); // Number in.getUpperBounds(); // Object out.getLowerBounds(); // Object out.getUpperBounds(); // Number } } ``` ### 一个参数 #### 字段 ```Java List listRawType; List<String> listString; Map mapRawType; Map<String, Object> mapString2Object; ``` 最后修改:2020 年 03 月 26 日 © 允许规范转载 赞 0 如果觉得我的文章对你有用,请随意赞赏