Java 中的 Type 类型详解,javase 菜鸟教程
f = TestParameterizedTypeBean.class.getDeclaredField(name);f.setAccessible(true);Type type = f.getGenericType();if (type instanceof ParameterizedType){for(Type param : ((ParameterizedType)type).getActualTypeArguments()){//打印实际参数类型 System.out.println("---type actualType---" + param.toString());}//打印所在的父类的类型 System.out.println("---type ownerType0---"+ ((ParameterizedType) type).getOwnerType());//打印其本身的类型 System.out.println("---type rawType---"+ ((ParameterizedType) type).getRawType());}} catch (NoSuchFieldException e) {e.printStackTrace();}}
上面的代码主要是定义了一些变量,这些变量中间有 ParameterizedType 也有普通类型变量,我们来看一下上述代码的输出:
TypeVariable:类型变量
范型信息在编译时会被转换为一个特定的类型, 而 TypeVariable 就是用来反映在 JVM 编译该泛型前的信息。(通俗的来说,TypeVariable 就是我们常用的 T,K 这种泛型变量)
getBounds(): Type[]:
返回当前类型的上边界,如果没有指定上边界,则默认为 Object。
getName(): String:
返回当前类型的类名
getGenericDeclaration(): D
返回当前类型所在的类的 Type。
下面通过一个例子来加深了解:
public class TestTypeVariableBean<K extends Number, T> {
//K 有指定了上边界 NumberK key;//T 没有指定上边界,其默认上边界为 ObjectT value;
public static void main(String[] args){Type[] types = TestTypeVariableBean.class.getTypeParameters();for (Type type : types){TypeVariable t = (TypeVariable) type;int index = t.getBounds().length - 1;//输出上边界 System.out.println("--getBounds()-- " + t.getBounds()[index]);//输出名称 System.out.println("--getName()--" + t.getName());//输出所在的类的类型 System.out.println("--getGenericDeclaration()--" + t.getGenericDeclaration());}}}
再来看下输出:
GenericArrayType:泛型数组类型:
组成数组的元素中有泛型则实现了该接口; 它的组成元素是 ParameterizedType 或 TypeVariable 类型。(通俗来说,就是由参数类型组成的数组。如果仅仅是参数化类型,则不能称为泛型数组,而是参数化类型)。注意:无论从左向右有几个[]并列,这个方法仅仅脱去最右边的[]之后剩下的内容就作为这个方法的返回值。
getGenericComponentType(): Type:
返回组成泛型数组的实际参数化类型,如 List[] 则返回 List。
下面还是通过一个例子来深入了解:
public class TestGenericArrayTypeBean<T> {
//泛型数组类型 private T[] value;private List<String>[] list;
//不是泛型数组类型 private List<String> singleList;private T singleValue;
public static void main(String[] args){Field[] fields = TestGenericArrayTypeBean.class.getDeclaredFields();for (Field field: fields){field.setAccessible(true);//输出当前变量是否为 GenericArrayType 类型 System.out.println("Field: "
field.getName()
"; instanceof GenericArrayType"
": "
(field.getGenericType() instanceof GenericArrayType));if (field.getGenericType() instanceof GenericArrayType){//如果是 GenericArrayType,则输出当前泛型类型 System.out.println("Field: "
field.getName()
"; getGenericComponentType()"
": "
(((GenericArrayType) field.getGenericType()).getGenericComponentType()));}}}}
接下来看下输出:
WildcardType: 通配符类型
表示通配符类型,比如 <?>, <? Extends Number>等
getLowerBounds(): Type[]: 得到下边界的数组
getUpperBounds(): Type[]: 得到上边界的 type 数组
注:如果没有指定上边界,则默认为 Object,如果没有指定下边界,则默认为 String
下面还是通过一个例子了解一下:
public class TestWildcardType {
public static void main(String[] args){//获取 TestWildcardType 类的所有方法(本例中即 testWildcardType 方法)Method[] methods = TestWildcardType.class.getDeclaredMethods();for (Method method: methods){//获取方法的所有参数类型 Type[] types = method.getGenericParameterTypes();for (Type paramsType: types){System.out.println("type: " + paramsType.toString());//如果不是参数化类型则直接 continue,执行下一个循环条件 if (!(paramsType instanceof ParameterizedType)){continue;}//将当前类型强转为参数化类型并获取其实际参数类型(即含有通配符的泛型类型)Type type = ((ParameterizedType) paramsType).getActualTypeArguments()[0];//输出其是否为通配符类型 System.out.println("type instanceof WildcardType : " +( type instanceof WildcardType));if (type instanceof WildcardType){int lowIndex = ((WildcardType) type).getLowerBounds().length - 1;int upperIndex = ((WildcardType) type).getUpperBounds().length - 1;//输出上边界与下边界 System.out.println("getLowerBounds(): "+(lowIndex >= 0 ? ((WildcardType) type).getLowerBounds()[lowIndex] : "String ")
"; getUpperBounds()
: "+
评论