Java类型中ParameterizedType,GenericArrayType,TypeVariabl,WildcardType详解
和反射+泛型有关的接口类型
- java.lang.reflect.Type:java语言中所有类型的公共父接口
- java.lang.reflect.ParameterizedType
- java.lang.reflect.GenericArrayType
- java.lang.reflect.WildcardType
- java.lang.reflect.TypeVariable
1. Type直接子接口
ParameterizedType,GenericArrayType,TypeVariable和WildcardType四种类型的接口
- ParameterizedType: 表示一种参数化的类型,比如Collection
- GenericArrayType: 表示一种元素类型是参数化类型或者类型变量的数组类型
- TypeVariable: 是各种类型变量的公共父接口
- WildcardType: 代表一种通配符类型表达式,比如?, ? extends Number, ? super Integer【wildcard是一个单词:就是“通配符”】
2. Type直接实现子类 :Class类
3. java.lang.reflect.Type接口
Type所有类型指代的有:原始类型 (raw types)【对应Class】,参数化类型 (parameterizedtypes)【对应ParameterizedType】, 数组类型 (array types)【对应GenericArrayType】,类型变量 (type variables)【对应TypeVariable】,基本数据类型(primitivetypes)【仍然对应Class】
4. java.lang.reflect.ParameterizedType接口
ParameterizedType接口类型的含义: 表示参数化类型。比如:Map这种参数化类型
获取参数化类型<>中的实际类型 ===》源码声明:Type[] getActualTypeArguments();
【注意】无论<>中有几层<>嵌套,这个方法仅仅脱去最外层的<>之后剩下的内容就作为这个方法的返回值。
例子如下:
public class TestController {
public static void main(String[] args) throws Exception {
TestController testController = new TestController(); //获取当前类
Method testParam = testController.getClass().getMethod("testParam", ArrayList.class, ArrayList.class, ArrayList.class, ArrayList.class, ArrayList.class); //获取下面的方法
Type[] genericParameterTypes = testParam.getGenericParameterTypes(); //获取方法泛型类参数
for (Type genericParameterType : genericParameterTypes) {
if (genericParameterType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericParameterType; //强转为泛型类
Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); //获取泛型真实声明的类型,调用一次只会去掉最外层的一个<>
for (Type actualTypeArgument : actualTypeArguments) {
System.out.println(actualTypeArgument.getTypeName()); //打印真实类型
}
}
}
}
public <E> E testParam(ArrayList<ArrayList<Integer>> al1,
ArrayList<E> al2,
ArrayList<String> al3,
ArrayList<? extends Number> al4,
ArrayList<E[]> al5){
Type genericSuperclass = this.getClass().getGenericSuperclass();
Class<?> superclass1 = this.getClass().getSuperclass();
Type genericSuperclass1 = al1.getClass().getGenericSuperclass();
Class<?> superclass = al1.getClass().getSuperclass();
Type aClass = al1.getClass();
if (aClass instanceof ParameterizedType) {
ParameterizedType p1 = (ParameterizedType) aClass;
}
return al2.get(0);
}
}
打印如下:
java.util.ArrayList<java.lang.Integer> // 由此可见只脱去了一层<> E java.lang.String ? extends java.lang.Number E[]
如上方法,那么它的每一参数总体上看都是参数化类型的。
5、 java.lang.reflect. GenericArrayType接口
GenericArrayType接口类型的含义:表示泛型数组类型。比如:void method(E[] al){…} 其中的E[] 就是该接口类型
获取泛型数组中元素的类型===》 源码声明:Type getGenericComponentType();
【注意】无论从左向右有几个[]并列,这个方法仅仅脱去最右边的[]之后剩下的内容就作为这个方法的返回值。
例子如下:
import java.lang.reflect.GenericArrayType; import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.lang.reflect.Type; import java.util.ArrayList; /** * @author Green * @date 2021年12月31日 2:31 下午 */ public class Test { public static void main(String[] args) throws Exception { Test test = new Test(); Method methodV = test.getClass().getMethod("methodV",String.class, String[].class, Object[].class, ArrayList[].class, Object[][].class); Parameter[] parameters = methodV.getParameters(); for (Parameter parameter : parameters) { Type parameterizedType = parameter.getParameterizedType(); //获取参数类型 if (GenericArrayType.class.isInstance(parameterizedType)) { // 参数3、4是泛型数组,会走这里 Type genericComponentType = ((GenericArrayType) parameterizedType).getGenericComponentType(); System.out.println(genericComponentType.getTypeName()); } if (Class.class.isInstance(parameterizedType)) { // 参数1、2、4会走这里,是Class类型 System.out.println(((Class) parameterizedType).getTypeName()); } } } public <E> E methodV( String p11, String[] p1, E[] p2, ArrayList[] p3, E[][] p4){ return p2[0]; } }
打印如下:
java.lang.String
java.lang.String[]
E
java.util.ArrayList[]
E[]
6、java.lang.reflect.TypeVariable接口
TypeVariable接口类型的含义: 表示泛型类型参数或者又叫做类型变量。比如:void method(E e){}中的E就是该接口类型
(这里经过验证,发现后面的内容转载说的不对,所以没有复制进来,看这篇:https://www.cnblogs.com/cainiao-Shun666/p/15754113.html 转载博客会说明该接口用法)
7、java.lang.reflect.WildcardType接口
WildcardType接口类型的含义 :表示通配符类型的表达式
这个接口说明也参考看下一篇转载博客;
转载:https://blog.csdn.net/smart_snail/article/details/69295224
看这篇转载博客更清晰:https://www.cnblogs.com/cainiao-Shun666/p/15754113.html