当前位置: 首页 > ai >正文

TypeReference 泛型的使用场景及具体使用流程

简介

在 Java 中,泛型类型在运行时会被擦除。这意味着当我们使用泛型时,运行时无法直接获取到泛型的具体类型信息。例如,我们无法直接通过 Class 对象来获取一个泛型类型的类型参数。这在某些情况下可能会导致问题,特别是在我们需要对泛型类型进行反射操作时。

TypeReference 是 Jackson 库提供的一个类,它可以帮助我们解决这个问题。通过 TypeReference,我们可以在运行时保留泛型的类型信息,从而能够正确地处理复杂的泛型类型。

本文将详细介绍 TypeReference 泛型的使用场景及具体使用流程,并通过一个实际例子展示如何在自定义 HttpClient 中使用 TypeReference

使用场景

处理复杂泛型的 JSON 反序列化

在使用 Jackson 库进行 JSON 反序列化时,如果目标类型是一个复杂的泛型类型,直接使用 Class 对象可能会导致类型擦除问题,从而无法正确地反序列化。例如,我们有一个泛型类 Map<String, List<String>>,如果我们直接使用 Class<Map<String, List<String>>> 来进行反序列化,会因为类型擦除而无法正确地获取到具体的泛型类型参数。

通过 TypeReference,我们可以正确地指定泛型类型参数,从而能够正确地反序列化复杂的泛型类型。

处理复杂泛型的反射操作

在进行反射操作时,我们可能需要获取泛型类型的类型参数。由于类型擦除,直接使用 Class 对象无法获取到这些类型参数。而 TypeReference 可以帮助我们保留这些类型参数,从而能够正确地进行反射操作。

具体使用流程

引入 Jackson 依赖

在使用 TypeReference 之前,我们需要先引入 Jackson 的依赖。如果你使用的是 Maven 项目,可以在 pom.xml 文件中添加以下依赖:

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.13.3</version>
</dependency>

定义 TypeReference 的子类

为了使用 TypeReference,我们需要定义一个 TypeReference 的子类。这个子类需要继承自 TypeReference,并且指定具体的泛型类型。例如,如果我们需要处理 Map<String, List<String>> 类型,可以这样定义:

new TypeReference<Map<String, List<String>>>() {};

使用 TypeReference 进行 JSON 反序列化

在使用 Jackson 进行 JSON 反序列化时,我们可以使用 TypeReference 来指定具体的泛型类型。例如:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;import java.io.IOException;
import java.util.List;
import java.util.Map;public class TypeReferenceExample {public static void main(String[] args) throws IOException {String json = "{\"key1\":[\"value1\",\"value2\"],\"key2\":[\"value3\",\"value4\"]}";ObjectMapper objectMapper = new ObjectMapper();TypeReference<Map<String, List<String>>> typeReference = new TypeReference<Map<String, List<String>>>() {};Map<String, List<String>> map = objectMapper.readValue(json, typeReference);System.out.println(map);}
}

在上面的代码中,我们定义了一个 TypeReference<Map<String, List<String>>> 的子类,并将其传递给 ObjectMapperreadValue 方法。这样,Jackson 就可以正确地反序列化 JSON 字符串到 Map<String, List<String>> 类型。

使用 TypeReference 进行反射操作

在进行反射操作时,我们可以通过 TypeReference 获取泛型类型的类型参数。例如:

import com.fasterxml.jackson.core.type.TypeReference;import java.lang.reflect.Type;public class TypeReferenceReflectionExample {public static void main(String[] args) {TypeReference<Map<String, List<String>>> typeReference = new TypeReference<Map<String, List<String>>>() {};Type type = typeReference.getType();System.out.println(type);}
}

在上面的代码中,我们通过 TypeReferencegetType 方法获取了泛型类型的 Type 对象。这个 Type 对象包含了泛型类型的类型参数信息,我们可以使用它来进行反射操作。

实际例子:HttpClient 通用类实现

在实际开发中,我们经常需要与外部服务进行 HTTP 通信。为了提高代码的复用性和可维护性,我们通常会自定义一个 HttpClient 类,用于封装 HTTP 请求和响应处理。由于返回值类型不固定,我们可以使用 TypeReference 来实现一个通用的 HttpClient 类。

定义 HttpClient 类

我们定义一个通用的 HttpClient 类,用于发送 HTTP 请求并处理响应。这个类将使用 TypeReference 来支持返回值类型不固定的场景。

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;import java.io.IOException;public class HttpClient {private static final ObjectMapper objectMapper = new ObjectMapper();private static final CloseableHttpClient httpClient = HttpClients.createDefault();public static <T> T get(String url, TypeReference<T> typeReference) throws IOException {HttpGet httpGet = new HttpGet(url);try (CloseableHttpResponse response = httpClient.execute(httpGet)) {String jsonResponse = EntityUtils.toString(response.getEntity());return objectMapper.readValue(jsonResponse, typeReference);}}
}

使用 HttpClient 类

我们可以使用 HttpClient 类来发送 HTTP 请求,并指定返回值的类型。例如,假设我们有一个外部服务返回一个 Map<String, List<String>> 类型的 JSON 数据,我们可以这样使用 HttpClient 类:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;import java.util.List;
import java.util.Map;public class HttpClientExample {public static void main(String[] args) {try {String url = "https://api.example.com/data";Map<String, List<String>> result = HttpClient.get(url, new CustomTypeReference().mapReference);System.out.println(result);} catch (IOException e) {e.printStackTrace();}}
}

自定义 TypeReference

import java.util.List;
import java.util.Map;import com.fasterxml.jackson.core.type.TypeReference;/*** CustomTypeReference 自定义TypeReference** @author xxx* @since 2025/7/24*/
public class CustomTypeReference {public TypeReference<Map<String, List<String>>> mapReference =new TypeReference<Map<String, List<String>>>() {};
}

在上面的代码中,我们定义了一个 TypeReference<Map<String, List<String>>> 的子类,并将其传递给 HttpClient.get 方法。这样,HttpClient 类就可以正确地反序列化返回的 JSON 数据到 Map<String, List<String>> 类型。


至此,本次分享到此结束啦!!!

http://www.xdnf.cn/news/18496.html

相关文章:

  • GEO优化服务商:AI时代数字经济的新引擎——解码行业发展与技术创新实践
  • 【Spring Boot】集成Redis超详细指南 Redis在Spring Boot中的应用场景
  • kubernetes-dashboard使用http不登录
  • 【卷积神经网络详解与实例】1——计算机中的图像原理
  • 卓伊凡的开源战略与PHP-SG16加密技术深度解析-sg加密技术详解-卓伊凡
  • pixijs基础学习
  • pyecharts可视化图表-map:从入门到精通
  • 【手撕JAVA多线程:2.线程安全】 2.1.JVM层面的线程安全保证
  • C++算法·进制转换
  • DeepSeek V3.1深度解析:一个模型两种思维,迈向Agent时代的第一步!
  • 并查集详解
  • 基于Python的农作物病虫害防治网站 Python+Django+Vue.js
  • 说说你对Integer缓存的理解?
  • 文献阅读笔记【物理信息机器学习】:Physics-informed machine learning
  • 【秋招笔试】2025.08.23美团研发岗秋招笔试题
  • SpringBoot applicationContext.getBeansOfType获取某一接口所有实现类,应用于策略模式
  • 深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)第五章整理
  • 墨刀原型设计工具操作使用指南及实践操作
  • 玩转Vue3高级特性:Teleport、Suspense与自定义渲染
  • 【假设微调1B模型,一个模型参数是16bit,计算需要多少显存?】
  • 【ABAP4】创建Package
  • 【力扣 Hot100】每日一题
  • Agent原理、构建模式(附视频链接)
  • 深度解析Bitmap、RoaringBitmap 的原理和区别
  • 讲点芯片验证中的统计覆盖率
  • 【攻防世界】easyupload
  • 量子计算驱动的Python医疗诊断编程前沿展望(上)
  • WSL Ubuntu数据迁移
  • 【数据分析】宏基因组荟萃分析(Meta-analysis)的应用与实操指南
  • 容器安全实践(三):信任、约定与“安全基线”镜像库