首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Gson源碼解析:Class到Type的向上轉型與類型擦除應對

     編輯:程式設計綜合問答

代碼片段

public Object fromJson(String json, Class classOfT) throws JsonSyntaxException {
    Object object = fromJson(json, (Type) classOfT); // 關鍵行
    return Primitives.wrap(classOfT).cast(object);
}

public Object fromJson(String json, Type typeOfT) throws JsonSyntaxException { ... }

核心問題

`Class` 到 `Type` 的強制轉換 `(Type) classOfT` 是什麼意思?為什麼需要?

類型層次關係

java.lang.reflect.Type (接口)
    ↑ 實現
java.lang.Class (類)
    ↑ 繼承
java.lang.Object
  • `Type` 是 Java 反射中**所有類型的公共父接口**
  • `Class` 實現了 `Type` 接口
  • 其他實現:`ParameterizedType`(泛型類型)、`GenericArrayType`(泛型數組)、`TypeVariable`(類型變量)、`WildcardType`(通配符類型)

為什麼要轉型?

Gson 內部解析邏輯統一處理 `Type` 對象,以支持完整泛型類型信息:

  • `Class` → 擦除後類型,無泛型參數
  • `Type` 可為 `ParameterizedType` → 保留 `List` 完整信息

當調用 `fromJson(json, MyClass.class)` 時,`classOfT` 是 `Class`,向上轉型為 `Type` 後,內部按「原始類型」處理。

關鍵場景:保留泛型信息

// 錯誤:類型擦除,無法正確反序列化泛型集合
List list = gson.fromJson(json, List.class); // 得到 List

// 正確:使用 TypeToken 保留完整泛型信息
Type listType = new TypeToken>() {}.getType();
List list = gson.fromJson(json, listType); // 正確得到 List

`TypeToken` 利用**匿名內部類繼承捕獲泛型簽名**,繞過類型擦除。

總結

  • `(Type) classOfT` 是**安全的向上轉型**(`Class` 實現 `Type`)
  • 目的:統一內部解析入口為 `Type`,支持更豐富的類型表示
  • 若需保留泛型參數,必須傳遞 `ParameterizedType`(通過 `TypeToken` 構造)而非 `Class`
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved