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