ParameterizedType 接口
ParameterizedType 接口声明了三个方法。
- Type[] getActualTypeArguments()
- Type getRawType()
- Type getOwnerType()
//例1 public class test { class ParameterizedClass { List list1; List<Integer> list2; Map map1; Map<String, Integer> map2; Map.Entry<String, Long> map3; List<Map<String,Integer>> map4; } public static void main(String[] args) { Field[] fields = ParameterizedClass.class.getDeclaredFields(); for (Field f : fields) { if (f.getGenericType() instanceof ParameterizedType) { ParameterizedType pType = (ParameterizedType) f.getGenericType(); System.out.println("<!---"+ pType.getTypeName()+"---!>"); System.out.println("RawType: "+pType.getRawType().getTypeName()); Type ownerType = pType.getOwnerType(); if(ownerType == null){ System.out.println("OwnerType: Null"); }else{ System.out.println("OwnerType: "+ ownerType.getTypeName()); } Type[] types = pType.getActualTypeArguments(); for (Type t : types) { System.out.println("--->ActualTypeArguments:" + t.getTypeName()); } }else{ System.out.println("<!---" + f.getType() + "---!>"); } System.out.println(); } } }
返回如下:
<!---interface java.util.List---!>
<!---java.util.List<java.lang.Integer>---!>
RawType: java.util.List
OwnerType: Null
--->ActualTypeArguments:java.lang.Integer
<!---interface java.util.Map---!>
<!---java.util.Map<java.lang.String, java.lang.Integer>---!>
RawType: java.util.Map
OwnerType: Null
--->ActualTypeArguments:java.lang.String
--->ActualTypeArguments:java.lang.Integer
<!---java.util.Map$Entry<java.lang.String, java.lang.Long>---!>
RawType: java.util.Map$Entry
OwnerType: java.util.Map
--->ActualTypeArguments:java.lang.String
--->ActualTypeArguments:java.lang.Long
<!---java.util.List<java.util.Map<java.lang.String, java.lang.Integer>>---!>
RawType: java.util.List
OwnerType: Null
--->ActualTypeArguments:java.util.Map<java.lang.String, java.lang.Integer>
<!---class test---!>
//例2 public class test2 { private static List<Map<String,Integer>> mapList; public static void main(String[] args) throws Exception{ Field field = test2.class.getDeclaredField("mapList"); System.out.println("<!---- " + field.getName() + "----!>"); ParameterizedType fParaType = (ParameterizedType) field.getGenericType(); System.out.println("GenericType: " + fParaType.getTypeName()); ParameterizedType pParaType = (ParameterizedType)fParaType.getActualTypeArguments()[0]; System.out.println("Generic -> Arguments: " + pParaType.getTypeName()); Type[] mapArgTypes = pParaType.getActualTypeArguments(); Class<?> mapArgType1 = (Class<?>)mapArgTypes[0]; System.out.println("Generic -> Arguments -> ArgumentsType1: " + mapArgType1.getTypeName()); Class<?> mapArgType2 = (Class<?>)mapArgTypes[1]; System.out.println("Generic -> Arguments -> ArgumentsType2: " + mapArgType2.getTypeName()); } }
返回如下:
<!---- mapList----!>
GenericType: java.util.List<java.util.Map<java.lang.String, java.lang.Integer>>
Generic -> Arguments: java.util.Map<java.lang.String, java.lang.Integer>
Generic -> Arguments -> ArgumentsType1: java.lang.String
Generic -> Arguments -> ArgumentsType2: java.lang.Integer
由于Java类型擦除的原因,只有编译时确定的成员变量的泛型信息会被完整保留。临时创建的变量无法储存泛型信息,因此也获取不到。
WildcardType 接口
- Type[] getUpperBounds()
- Type[] getLowerBounds()
用于获取类在关系中的上界和下界。
其中 extends 是上界通配符,super 是下界通配符。? super classA 表示这个类是 classA 的父类。但不确定是哪个。因此处理时转到上界 Object,会失去很多信息。? extends classB 表示这个类是 classB的子类,但是classB的子类有多种的情况下,可能会获取错误的对象。
public class test3 { class plant{ } class fruit extends plant{ } class apple extends fruit{ } public static List<? super fruit> list; public static void main(String[] args) throws Exception { Field field = test3.class.getDeclaredField("list"); ParameterizedType parameterizedType = (ParameterizedType)field.getGenericType(); Type type = parameterizedType.getActualTypeArguments()[0]; System.out.println(type.getTypeName()); if(type instanceof WildcardType){ WildcardType wildcardType = (WildcardType)type; Type[] upperBounds = wildcardType.getUpperBounds(); Type[] lowerBounds = wildcardType.getLowerBounds(); if(upperBounds.length != 0){ System.out.println(upperBounds[0].getTypeName()); }else{ System.out.println("UpperBounds is null."); } if(lowerBounds.length > 0){ System.out.println(lowerBounds[0].getTypeName()); }else{ System.out.println("LowerBounds is null."); } } } }
? super test3$fruit
java.lang.Object
test3$fruit