一、前言
关于flink-core源码包中的org.apache.flink.util.ReflectionUtil反向映射工具类,获取父类getSuperTemplateTypes类、获取类getTemplateType父类方法入参类型等操作。
二、源码说明
package org.apache.flink.util;@b@@b@import org.apache.flink.annotation.Internal;@b@@b@import java.lang.reflect.ParameterizedType;@b@import java.lang.reflect.Type;@b@import java.util.Arrays;@b@import java.util.Collections;@b@import java.util.Iterator;@b@@b@@Internal@b@public final class ReflectionUtil {@b@ public static <T> T newInstance(Class<T> clazz) {@b@ try {@b@ return clazz.newInstance();@b@ } catch (Exception e) {@b@ throw new RuntimeException(e);@b@ }@b@ }@b@@b@ @SuppressWarnings("unchecked")@b@ public static <T> Class<T> getTemplateType(Class<?> clazz, int num) {@b@ return (Class<T>) getSuperTemplateTypes(clazz)[num];@b@ }@b@ @b@ @SuppressWarnings("unchecked")@b@ public static <T> Class<T> getTemplateType(Class<?> clazz, Class<?> classWithParameter, int num) {@b@ return (Class<T>) getSuperTemplateTypes(clazz)[num];@b@ }@b@ @b@ public static <T> Class<T> getTemplateType1(Class<?> clazz) {@b@ return getTemplateType(clazz, 0);@b@ }@b@@b@ public static <T> Class<T> getTemplateType1(Type type) {@b@ if (type instanceof ParameterizedType) {@b@ return (Class<T>) getTemplateTypes((ParameterizedType) type)[0];@b@ } else {@b@ throw new IllegalArgumentException();@b@ }@b@ }@b@@b@ public static <T> Class<T> getTemplateType2(Class<?> clazz) {@b@ return getTemplateType(clazz, 1);@b@ }@b@@b@ public static <T> Class<T> getTemplateType3(Class<?> clazz) {@b@ return getTemplateType(clazz, 2);@b@ }@b@@b@ public static <T> Class<T> getTemplateType4(Class<?> clazz) {@b@ return getTemplateType(clazz, 3);@b@ }@b@@b@ public static <T> Class<T> getTemplateType5(Class<?> clazz) {@b@ return getTemplateType(clazz, 4);@b@ }@b@@b@ public static <T> Class<T> getTemplateType6(Class<?> clazz) {@b@ return getTemplateType(clazz, 5);@b@ }@b@@b@ public static <T> Class<T> getTemplateType7(Class<?> clazz) {@b@ return getTemplateType(clazz, 6);@b@ }@b@@b@ public static <T> Class<T> getTemplateType8(Class<?> clazz) {@b@ return getTemplateType(clazz, 7);@b@ }@b@@b@ public static Class<?>[] getSuperTemplateTypes(Class<?> clazz) {@b@ Type type = clazz.getGenericSuperclass();@b@ while (true) {@b@ if (type instanceof ParameterizedType) {@b@ return getTemplateTypes((ParameterizedType) type);@b@ }@b@@b@ if (clazz.getGenericSuperclass() == null) {@b@ throw new IllegalArgumentException();@b@ }@b@@b@ type = clazz.getGenericSuperclass();@b@ = clazz.getSuperclass();@b@ }@b@ }@b@ @b@ public static Class<?>[] getSuperTemplateTypes(Class<?> clazz, Class<?> searchedSuperClass) {@b@ if (clazz == null || searchedSuperClass == null) {@b@ throw new NullPointerException();@b@ }@b@ @b@ Class<?> superClass = null;@b@ do {@b@ superClass = clazz.getSuperclass();@b@ if (superClass == searchedSuperClass) {@b@ break;@b@ }@b@ }@b@ while ((clazz = superClass) != null);@b@ @b@ if (clazz == null) {@b@ throw new IllegalArgumentException("The searched for superclass is not a superclass of the given class.");@b@ }@b@ @b@ final Type type = clazz.getGenericSuperclass();@b@ if (type instanceof ParameterizedType) {@b@ return getTemplateTypes((ParameterizedType) type);@b@ }@b@ else {@b@ throw new IllegalArgumentException("The searched for superclass is not a generic class.");@b@ }@b@ }@b@@b@ public static Class<?>[] getTemplateTypes(ParameterizedType paramterizedType) {@b@ Class<?>[] types = new Class<?>[paramterizedType.getActualTypeArguments().length];@b@ int i = 0;@b@ for (Type templateArgument : paramterizedType.getActualTypeArguments()) {@b@ assert templateArgument instanceof Class<?>;@b@ types[i++] = (Class<?>) templateArgument;@b@ }@b@ return types;@b@ }@b@@b@ public static Class<?>[] getTemplateTypes(Class<?> clazz) {@b@ Type type = clazz.getGenericSuperclass();@b@ assert (type instanceof ParameterizedType);@b@ ParameterizedType paramterizedType = (ParameterizedType) type;@b@ Class<?>[] types = new Class<?>[paramterizedType.getActualTypeArguments().length];@b@ int i = 0;@b@ for (Type templateArgument : paramterizedType.getActualTypeArguments()) {@b@ assert (templateArgument instanceof Class<?>);@b@ types[i++] = (Class<?>) templateArgument;@b@ }@b@ return types;@b@ }@b@@b@ /**@b@ * Extract the full template type information from the given type's template parameter at the@b@ * given position.@b@ *@b@ * @param type type to extract the full template parameter information from@b@ * @param templatePosition describing at which position the template type parameter is@b@ * @return Full type information describing the template parameter's type@b@ */@b@ public static FullTypeInfo getFullTemplateType(Type type, int templatePosition) {@b@ if (type instanceof ParameterizedType) {@b@ return getFullTemplateType(((ParameterizedType) type).getActualTypeArguments()[templatePosition]);@b@ } else {@b@ throw new IllegalArgumentException();@b@ }@b@ }@b@@b@ /**@b@ * Extract the full type information from the given type.@b@ *@b@ * @param type to be analyzed@b@ * @return Full type information describing the given type@b@ */@b@ public static FullTypeInfo getFullTemplateType(Type type) {@b@ if (type instanceof ParameterizedType) {@b@ ParameterizedType parameterizedType = (ParameterizedType) type;@b@@b@ FullTypeInfo[] templateTypeInfos = new FullTypeInfo[parameterizedType.getActualTypeArguments().length];@b@@b@ for (int i = 0; i < parameterizedType.getActualTypeArguments().length; i++) {@b@ templateTypeInfos[i] = getFullTemplateType(parameterizedType.getActualTypeArguments()[i]);@b@ }@b@@b@ return new FullTypeInfo((Class<?>)parameterizedType.getRawType(), templateTypeInfos);@b@ } else {@b@ return new FullTypeInfo((Class<?>) type, null);@b@ }@b@ }@b@@b@ /**@b@ * Container for the full type information of a type. This means that it contains the@b@ * {@link Class} object and for each template parameter it contains a full type information@b@ * describing the type.@b@ */@b@ public static class FullTypeInfo {@b@ private final Class<?> clazz;@b@ private final FullTypeInfo[] templateTypeInfos;@b@@b@@b@ public FullTypeInfo(Class<?> clazz, FullTypeInfo[] templateTypeInfos) {@b@ this.clazz = Preconditions.checkNotNull(clazz);@b@ this.templateTypeInfos = templateTypeInfos;@b@ }@b@@b@ public Class<?> getClazz() {@b@ return clazz;@b@ }@b@@b@ public FullTypeInfo[] getTemplateTypeInfos() {@b@ return templateTypeInfos;@b@ }@b@@b@ public Iterator<Class<?>> getClazzIterator() {@b@ UnionIterator<Class<?>> unionIterator = new UnionIterator<>();@b@@b@ unionIterator.add(Collections.<Class<?>>singleton(clazz).iterator());@b@@b@ if (templateTypeInfos != null) {@b@ for (int i = 0; i < templateTypeInfos.length; i++) {@b@ unionIterator.add(templateTypeInfos[i].getClazzIterator());@b@ }@b@ }@b@@b@ return unionIterator;@b@ }@b@@b@ @Override@b@ public String toString() {@b@ StringBuilder builder = new StringBuilder();@b@@b@ builder.append(clazz.getSimpleName());@b@@b@ if (templateTypeInfos != null) {@b@ builder.append("<");@b@@b@ for (int i = 0; i < templateTypeInfos.length - 1; i++) {@b@ builder.append(templateTypeInfos[i]).append(", ");@b@ }@b@@b@ builder.append(templateTypeInfos[templateTypeInfos.length - 1]);@b@ builder.append(">");@b@ }@b@@b@ return builder.toString();@b@ }@b@@b@ @Override@b@ public boolean equals(Object obj) {@b@ if (obj instanceof FullTypeInfo) {@b@ FullTypeInfo other = (FullTypeInfo) obj;@b@@b@ return clazz == other.getClazz() && Arrays.equals(templateTypeInfos, other.getTemplateTypeInfos());@b@ } else {@b@ return false;@b@ }@b@ }@b@ }@b@@b@ /**@b@ * Private constructor to prevent instantiation.@b@ */@b@ private ReflectionUtil() {@b@ throw new RuntimeException();@b@ }@b@}