知識庫 / JSON / Jackson RSS 訂閱

Jackson 泛型類型反序列化

Jackson
HongKong
6
09:47 PM · Dec 05 ,2025

1. 背景

Jackson 是一個流行的 Java 庫,用於將 Java 對象序列化為 JSON,以及反向序列化 JSON 為 Java 對象。在某些情況下,Java 對象可能被定義為具有泛型類型。

在本教程中,我們將演示如何使用 Jackson 將 JSON 字符串反序列化為泛型類型。

2. 模型準備

對於要進行反序列化的給定的 JSON 字符串:

{"result":{"id":1,"firstName":"John","lastName":"Lewis"}}

我們需要定義一個類,該類具有泛型類型參數和一個常規的POJO對象來存儲數據:

public class JsonResponse<T> {
    private T result;

    // getters and setters...
}
public class User {
    private Long id;
    private String firstName;
    private String lastName;

    // getters and setters...
}

3. 解序列化泛型類型

在 Jackson 中,<em>ObjectMapper</em> 提供了三個用於 JSON 解序列化的 <em>readValue</em> 方法集合,它們接受:

  • Class<T> 作為參數,用於傳遞信息類型
  • TypeReference 用於傳遞類型信息
  • JavaType 作為參數

我們不能使用 <em>JsonResponse&lt;User&gt;.class</em> 傳遞到第一個 bullet point 中的方法,讓我們看看如何使用 <em>TypeReference</em><em>JavaType</em> 進行泛型解序列化。

3.1. <em >TypeReference</em>

如我們所知,Java 在編譯時會擦除泛型類型信息,但我們可以利用匿名內部類強大的功能,在編譯期間保留類型信息。Jackson 提供了抽象類 <em >TypeReference</em>,用於從派生子類獲取類型信息:

public abstract class TypeReference<T> { 
    protected final Type _type;

    protected TypeReference() {
        Type superClass = this.getClass().getGenericSuperclass();
        this._type = ((ParameterizedType)superClass).getActualTypeArguments()[0]; 
    } 
}

使用 TypeReference,我們可以為泛型類型 JsonResponse<User> 創建一個匿名內部類,如下所示:

TypeReference<JsonResponse<User>> typeRef = new TypeReference<JsonResponse<User>>() {};

這種用於保留泛型類型信息的方案被稱為超類型標記(super type token)。通過使用超類型標記,Jackson 將知道容器類型是 JsonResponse ,其類型參數是 User

以下是反序列化的完整測試用例:

@Test
void givenJsonObject_whenDeserializeIntoGenericTypeByTypeReference_thenCorrect() throws JsonProcessingException {
    String json = "{\"result\":{\"id\":1,\"firstName\":\"John\",\"lastName\":\"Lewis\"}}";

    TypeReference<JsonResponse<User>> typeRef = new TypeReference<JsonResponse<User>>() {};
    JsonResponse<User> jsonResponse = objectMapper.readValue(json, typeRef);
    User user = jsonResponse.getResult();

    assertThat(user.getId()).isEqualTo(1);
    assertThat(user.getFirstName()).isEqualTo("John");
    assertThat(user.getLastName()).isEqualTo("Lewis");
}

3.2. <em >JavaType</em>

如果類型參數 <em >T</em> 不是靜態的,則需要使用 <em >JavaType</em> 而不是 <em >TypeReference</em> 來傳遞解序列化所需的類型信息。<em >ObjectMapper</em> 提供了這樣的方法,並且從 Jackson 2.5 版本開始,現在推薦使用它們。我們可以使用 <em >TypeFactory</em> 來構造包含我們類型參數的 <em >JavaType</em> 對象:

JavaType javaType = objectMapper.getTypeFactory().constructParametricType(JsonResponse.class, User.class);
JsonResponse<User> jsonResponse = objectMapper.readValue(json, javaType);

這裏 作為第二個參數傳遞給 方法,可以輕鬆地更改為其他參數化類型。

4. 結論

在本文中,我們介紹了兩種將 JSON 字符串反序列化為具有泛型類型的對象的簡單方法。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.