首先 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 )