关于 TypeReference 的解释

首先 TypeReference  是描述 一个复杂 泛型的工具类。

TypeReference 很多类库都有,用 fastjson 的 举例,大概就这个意思。

例子:

Response<FeedInRespData> response = JSONObject.parseObject(result, new TypeReference<Response<FeedInRespData>>() {});

new TypeReference<Response<FeedInRespData>>() {} 描述的是一个   这个样的 类: Response<FeedInRespData>,同理,可以更多层的嵌套泛型。

当 TypeReference 的泛型参数是 泛型变量的时候。可用使用 参数来修饰泛型变量。

我们看看 TypeReference 构造方法的源码:

 protected TypeReference(){
Type superClass = getClass().getGenericSuperclass(); Type type = ((ParameterizedType) superClass).getActualTypeArguments()[0]; Type cachedType = classTypeCache.get(type);
if (cachedType == null) {
classTypeCache.putIfAbsent(type, type);
cachedType = classTypeCache.get(type);
} this.type = cachedType;
} /**
* @since 1.2.9
* @param actualTypeArguments
*/
protected TypeReference(Type... actualTypeArguments){
Class<?> thisClass = this.getClass();
Type superClass = thisClass.getGenericSuperclass(); ParameterizedType argType = (ParameterizedType) ((ParameterizedType) superClass).getActualTypeArguments()[0];
Type rawType = argType.getRawType();
Type[] argTypes = argType.getActualTypeArguments(); int actualIndex = 0;
for (int i = 0; i < argTypes.length; ++i) {
if (argTypes[i] instanceof TypeVariable &&
actualIndex < actualTypeArguments.length) {
argTypes[i] = actualTypeArguments[actualIndex++];
}
// fix for openjdk and android env
if (argTypes[i] instanceof GenericArrayType) {
argTypes[i] = TypeUtils.checkPrimitiveArray(
(GenericArrayType) argTypes[i]);
}
} Type key = new ParameterizedTypeImpl(argTypes, thisClass, rawType);
Type cachedType = classTypeCache.get(key);
if (cachedType == null) {
classTypeCache.putIfAbsent(key, key);
cachedType = classTypeCache.get(key);
} type = cachedType; }

  

上面的 无参 构造方法 里面 获取了 参数泛型 (ParameterizedType),后面的 有差 构造方法 用参数 替换了 参数泛型中是  泛型变量 里面的 内容。

例子:Response<T> response = JSONObject.parseObject(result, new TypeReference<Response<T>>( respDatacls ) {});

等价于:Response<TaskCodeRespData> response = JJSONObject.parseObject(result, new TypeReference<Response<TaskCodeRespData>>( ) {})

如果要用泛型变量 ,有参数的写法就相当必要了。

备注:上面的  respDatacls  = TaskCodeRespData.class

备注:如果 T 是 泛型变量 ,如果 如果 没传后面的修饰参数 T 会被 识别成 T 的 上边界(  根据 T的定义 如果: <T extends RespData> T 被识别成 RespData  ,如果是<T> T被识别成 Object       )

上一篇:Dynamics AX 2012 R2 在增强入站端口中找不到自定义服务操作


下一篇:网络服务器带宽Mbps、Mb/s、MB/s有什么区别?10M、100M到底是什么概念?