Java Type类及其子类用途

Type

Type类为Java所有类型的通用接口

  public interface Type {
    default String getTypeName() {
        return toString();
    }
}

查看他的继承关系:
包括原始类型、参数化类型(Parameterized)、数组类型(GenericArrayType)、类型变量(TypeVariable)、通配符类型(WildcardType)和基本类型(Class);

接下来分开查看对应子类源码和测试其用法;

Parameterized

/**
 *  参数化类型也就是我们常用的泛型比如List等带泛型的都属于此类型
 */
public interface ParameterizedType extends Type {
    //获取参数化类型参数;比如Map;那么返回,K/V对应数组;
    Type[] getActualTypeArguments();
    //获取原始类型,泛型类型,例如:List 中为 List
    Type getRawType();
    //如果是内部类,获取拥有内部类的外部类例如Map.Entry中应该为Map
    Type getOwnerType();
}

测试一下:

public class ParameterizedTypeTest {
    private Map.Entry entry = null;

    public static void main(String[] args) {
        try {
            Field fieldList = ParameterizedTypeTest.class.getDeclaredField("entry");
            Type listType = fieldList.getGenericType();
            ParameterizedType listParameterizedType = (ParameterizedType) listType;
            Type[] listActualTypeArguments = listParameterizedType.getActualTypeArguments();
            Type listRawType = listParameterizedType.getRawType();
            Type listOwnType = listParameterizedType.getOwnerType();
            for (Type type : listActualTypeArguments) {
                System.out.println("listActualTypeArguments:" + type.getTypeName());
            }
            System.out.println("listRawType:" + listRawType.getTypeName());
            System.out.println("listOwnType:" + listOwnType.getTypeName());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

得到下面的输出结果:

listActualTypeArguments:java.lang.String
listActualTypeArguments:java.lang.Integer
listRawType:java.util.Map$Entry
listOwnType:java.util.Map

GenericArrayType

数组泛型类型;
查看源码:

/**
* 大致应该存在两种类型int[],List[];
*/
public interface GenericArrayType extends Type {
    //可以获取到数组前面的类型,比如:List[]为List
    Type getGenericComponentType();
}

看示例:

public class GenericArrayTypeTest {
    private T[] intArrays = null;
    private List[] listArrays = null;

    public static void main(String[] args) {
        try {
            Field intFiled = GenericArrayTypeTest.class.getDeclaredField("intArrays");
            Type intType = intFiled.getGenericType();
            GenericArrayType intGenericArrayType = (GenericArrayType) intType;
            System.out.println("intType:" + intType.getClass().getName());
            System.out.println("intGenericArrayType:" + intGenericArrayType.getGenericComponentType().getTypeName());

            Field listFiled = GenericArrayTypeTest.class.getDeclaredField("listArrays");
            Type listType = listFiled.getGenericType();
            GenericArrayType listGenericArrayType = (GenericArrayType) listType;
            System.out.println("listType:" + listType.getClass().getName());
            Type listCompinentType = listGenericArrayType.getGenericComponentType();
            System.out.println("listCompinentType:" + listCompinentType.getTypeName());
            System.out.println("listCompinentTypeClass:" + listCompinentType.getClass().getName());

        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

打印结果:

intType:sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl
intGenericArrayType:T
listType:sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl
listCompinentType:java.util.List
listCompinentTypeClass:sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl

TypeVariable

类型变量:

/**
* 真实泛型变量值:例如List中的T;
*/
public interface TypeVariable extends Type, AnnotatedElement {
    //获得该类型变量的上限,也就是泛型中extend右边的值;
     //例如 List ,Number就是类型变量T的上限;
    Type[] getBounds();
    //获取声明该类型变量实体
    D getGenericDeclaration();

    String getName();

    AnnotatedType[] getAnnotatedBounds();
}

不明白直接看示例:

public class TypeVariableTest {
    private Map map = null;

    public static void main(String[] args) {
        try {
            Field mapField = TypeVariableTest.class.getDeclaredField("map");
            Type mapType = mapField.getGenericType();
            System.out.println("mapType:" + mapType.getClass().getName());
            ParameterizedType mapParameterizedType = (ParameterizedType) mapType;
            Type[] mapParameterizedTypes = mapParameterizedType.getActualTypeArguments();
            for (Type mapParamType : mapParameterizedTypes) {
                System.out.println("mapParamType:" + mapParamType.getClass().getName());
                if (mapParamType instanceof TypeVariable) {
                    TypeVariable typeVariable = (TypeVariable) mapParamType;
                    System.out.println("typeVariable:" + typeVariable.getGenericDeclaration().toString());
                    for (Type boundsType : typeVariable.getBounds()) {
                        System.out.println("boundsType:" + boundsType.getTypeName());
                    }
                }
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

打印结果:

mapType:sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
mapParamType:java.lang.Class
mapParamType:sun.reflect.generics.reflectiveObjects.TypeVariableImpl
typeVariable:class com.xxx.lib.TypeVariableTest
boundsType:java.lang.Number

WildcardType

通配符类型;

/**
* 通配符类型;例如:List
*/
public interface WildcardType extends Type {
    //获取上边界List Number
    Type[] getUpperBounds();
    //获取下边界List String
    Type[] getLowerBounds();
}

看示例:

public class WildcardTypeTest {
    private List numbers;

    public static void main(String[] args) {
        try {
            Field numField = WildcardTypeTest.class.getDeclaredField("numbers");
            Type numType = numField.getGenericType();
            System.out.println("numType:" + numType.getClass().getName());
            ParameterizedType numsParameterizedType = (ParameterizedType) numType;
            for (Type actualType : numsParameterizedType.getActualTypeArguments()) {
                System.out.println("actualType:" + actualType.getClass().getName());
                WildcardType wildcardType = (WildcardType) actualType;
                Type[] uppperBounds = wildcardType.getUpperBounds();
                if (uppperBounds != null) {
                    for (Type upper : uppperBounds) {
                        System.out.println("upper:" + upper.getTypeName());
                        System.out.println("upper Type:" + upper.getClass().getName());
                    }
                }
                Type[] lowerBounds = wildcardType.getLowerBounds();
                if (lowerBounds != null) {
                    for (Type lower : lowerBounds) {
                        System.out.println("lower:" + lower.getTypeName());
                        System.out.println("lower Type:" + lower.getClass().getName());
                    }
                }
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }
}

输出结果:

numType:sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
actualType:sun.reflect.generics.reflectiveObjects.WildcardTypeImpl
upper:java.lang.Number
upper Type:java.lang.Class

现实应用,Retrofit的returnType是如何拿到的?

public  T create(final Class service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();
          private final Object[] emptyArgs = new Object[0];

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            //将method传递到后面
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }

loadServiceMethod调用HttpServiceMethod

private HttpServiceMethod(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
      CallAdapter callAdapter,
      Converter responseConverter) {
    this.requestFactory = requestFactory;
    this.callFactory = callFactory;
    this.callAdapter = callAdapter;
    this.responseConverter = responseConverter;
  }

  @Override ReturnT invoke(Object[] args) {
    //这里调用了callAdapter,继续跟进callAdapter
    return callAdapter.adapt(
        new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
  }

····

private static  CallAdapter createCallAdapter(
      Retrofit retrofit, Method method) {
    //这里可以看到从method上拿到了返回类型的returnType;但是这里我们通常都是Observable,最终传递给Converter的类型应该继续查看
    Type returnType = method.getGenericReturnType();
    Annotation[] annotations = method.getAnnotations();
    try {
      //可以看到这里直接调用了retrofit的callAdaper;这是使我们初始化的retrofit设置的CallAdapter
      return (CallAdapter) retrofit.callAdapter(returnType, annotations);
    } catch (RuntimeException e) { // Wide exception range because factories are user code.
      throw methodError(method, e, "Unable to create call adapter for %s", returnType);
    }
  }

直接追下RxJava2CallAdapterFactory

@Override public @Nullable CallAdapter get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    //这里有个获取真实类型的,看名字这里应该是我们需要找的,等会进入这个类再详细的解释
    Class rawType = getRawType(returnType);
  //删除部分无关代码
    .......
    
    Type responseType;
    //这里可以看到 会判断返回类型是不是参数化类型。不是直接返回,这里必须是Observable、Flow等,将我们上面的学习,是ParameterizedType,我们学习结果得到了验证
    if (!(returnType instanceof ParameterizedType)) {
      String name = isFlowable ? "Flowable"
          : isSingle ? "Single"
          : isMaybe ? "Maybe" : "Observable";
      throw new IllegalStateException(name + " return type must be parameterized"
          + " as " + name + " or " + name + "");
    }
    //// getParameterUpperBound到下面详细介绍
    Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
    Class rawObservableType = getRawType(observableType);
    if (rawObservableType == Response.class) {
      if (!(observableType instanceof ParameterizedType)) {
        throw new IllegalStateException("Response must be parameterized"
            + " as Response or Response");
      }
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
    } else if (rawObservableType == Result.class) {
      if (!(observableType instanceof ParameterizedType)) {
        throw new IllegalStateException("Result must be parameterized"
            + " as Result or Result");
      }
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
      isResult = true;
    } else {
      responseType = observableType;
      isBody = true;
    }

    return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
        isSingle, isMaybe, false);
  }

接下来我们看看getParameterUpperBound 和getRawType方法,他们最终调用Util中的方法,直接看对应方法

static Class getRawType(Type type) {
    checkNotNull(type, "type == null");

    if (type instanceof Class) {
      // 如果是class直接返回
      return (Class) type;
    }
    if (type instanceof ParameterizedType) {
  //如果是参数化类型
      ParameterizedType parameterizedType = (ParameterizedType) type;
      //拿到真实类型比如Observable 拿到Observable;
      Type rawType = parameterizedType.getRawType();
      if (!(rawType instanceof Class)) throw new IllegalArgumentException();
      return (Class) rawType;
    }
    if (type instanceof GenericArrayType) {
      Type componentType = ((GenericArrayType) type).getGenericComponentType();
    //如果是数组类型,通过Array.newInstance得到数组对象,然后拿到对应的class
      return Array.newInstance(getRawType(componentType), 0).getClass();
    }
    if (type instanceof TypeVariable) {
    //type直接是类型变量,这里直接返回了Object.class;我们可以根据边界继续寻找
      return Object.class;
    }
    if (type instanceof WildcardType) {
    //如果是通配符类型,拿到上边界类型,有可能有多个层级,继续调用getRawType
      return getRawType(((WildcardType) type).getUpperBounds()[0]);
    }

    throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
          + "GenericArrayType, but <" + type + "> is of type " + type.getClass().getName());
  }

static Type getParameterUpperBound(int index, ParameterizedType type) {
 //这个很简单就是获取对应泛型参数位置类型,如果是通配符类型拿上边界    
Type[] types = type.getActualTypeArguments();
    if (index < 0 || index >= types.length) {
      throw new IllegalArgumentException(
          "Index " + index + " not in range [0," + types.length + ") for " + type);
    }
    Type paramType = types[index];
    if (paramType instanceof WildcardType) {
      return ((WildcardType) paramType).getUpperBounds()[0];
    }
    return paramType;
  }

你可能感兴趣的:(Java Type类及其子类用途)