使用 GSON 和 Kotlin 泛型将 JSON 转换为自定义类

使用 gson 和 kotlin 泛型将 json 转换为自定义类

本文档旨在解决在使用 GSON 和 Kotlin 泛型进行 JSON 反序列化时,将 JSON 数据转换为自定义类时遇到的 ClassCastException 问题。通过分析问题原因,提供解决方案,并介绍未来 GSON 版本中对此类问题的改进,帮助开发者更好地理解和使用 GSON 进行 Kotlin 开发。

在使用 GSON 和 Kotlin 泛型进行 JSON 反序列化时,可能会遇到将 JSON 数据转换为自定义类时出现 ClassCastException 的问题,例如将 LinkedTreeMap 转换为自定义类。 这通常是由于类型信息在运行时丢失造成的。以下将详细介绍问题原因和解决方案。

问题分析

在上述示例代码中,问题出在 decodeFunctionReturnValue 函数中。由于类型参数 T 不是 reified,因此在运行时,TypeToken 实际上创建的是 TypeToken<JsonFunctionReturnValueData>。当反序列化 Object 时,GSON 基于 JSON 数据创建标准对象,对于 JSON 对象,GSON 会使用 Java 的 Map (内部实现是 LinkedTreeMap)。

解决方案

解决此问题的关键在于确保 GSON 在运行时能够获取到正确的类型信息。以下提供两种可能的解决方案:

将类型参数 T 设置为 reified

如果可能,将 decodeFunctionReturnValue 函数的类型参数 T 设置为 reified。这样,在运行时,类型信息将被保留,GSON 可以正确地将 JSON 数据反序列化为指定的自定义类。

inline fun  decodeFunctionReturnValue(data: String): T? {    try {        val type = object : TypeToken<JsonFunctionReturnValueData>() {}.type        val gson = createGson()        return gson.fromJson<JsonFunctionReturnValueData>(data, type).r    } catch (e: Exception) {        Log.e(            Constants.LOG_GROUP,            "[JsonSerializer : decodeFunctionReturnValue] Error when parse json: ${e.message}"        )    }    return null}

注意: reified 关键字只能用于 inline 函数。

将类型作为单独的 TypeToken 参数传递

如果无法将类型参数 T 设置为 reified,可以将类型作为单独的 TypeToken 参数传递给函数。

Find JSON Path Online Find JSON Path Online

Easily find JSON paths within JSON objects using our intuitive Json Path Finder

Find JSON Path Online 30 查看详情 Find JSON Path Online

fun  decodeFunctionReturnValue(data: String, typeToken: TypeToken<JsonFunctionReturnValueData>): T? {    try {        val gson = createGson()        return gson.fromJson<JsonFunctionReturnValueData>(data, typeToken.type).r    } catch (e: Exception) {        Log.e(            Constants.LOG_GROUP,            "[JsonSerializer : decodeFunctionReturnValue] Error when parse json: ${e.message}"        )    }    return null}

调用此函数时,需要提供正确的 TypeToken。例如:

val todoTypeToken = object : TypeToken<JsonFunctionReturnValueData>() {}val todo = decodeFunctionReturnValue(data, todoTypeToken)

示例代码

假设有以下 Todo 类:

data class Todo(val id: Int, val title: String, val completed: Boolean)

以及 JsonFunctionReturnValueData 类:

data class JsonFunctionReturnValueData(val r: T)

使用上述第二种解决方案的示例代码如下:

import com.google.gson.Gsonimport com.google.gson.reflect.TypeTokenimport android.util.Logobject JsonSerializer {    private fun createGson(): Gson {        return Gson() // You can customize Gson here if needed    }    fun  decodeFunctionReturnValue(data: String, typeToken: TypeToken<JsonFunctionReturnValueData>): T? {        try {            val gson = createGson()            return gson.fromJson<JsonFunctionReturnValueData>(data, typeToken.type)?.r        } catch (e: Exception) {            Log.e("JsonSerializer", "[JsonSerializer : decodeFunctionReturnValue] Error when parse json: ${e.message}")        }        return null    }}fun main() {    val jsonString = "{ "r": { "id": 1, "title": "Buy groceries", "completed": false } }"    val todoTypeToken = object : TypeToken<JsonFunctionReturnValueData>() {}    val todo = JsonSerializer.decodeFunctionReturnValue(jsonString, todoTypeToken)    println(todo) // Output: Todo(id=1, title=Buy groceries, completed=false)}

未来 GSON 版本改进

未来的 GSON 版本(> 2.10.1)将在 TypeToken 捕获类型变量时抛出异常,从而帮助开发者更早地发现此类问题。GSON 官方的 Troubleshooting Guide 提供了更多信息和解决方法

总结

在使用 GSON 和 Kotlin 泛型进行 JSON 反序列化时,需要注意类型信息的保留。 通过将类型参数设置为 reified 或将类型作为单独的 TypeToken 参数传递,可以解决 ClassCastException 问题。同时,关注 GSON 的未来版本更新,可以更早地发现和解决此类问题。

以上就是使用 GSON 和 Kotlin 泛型将 JSON 转换为自定义类的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/217586.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
拼音声调手机的应用和优势(提高学习效率)
上一篇 2025年11月3日 15:44:25
抖音店铺订单信息加密解密技巧
下一篇 2025年11月3日 15:44:31

相关推荐

  • Java中反射机制的优缺点及适用场景探讨

    Java中反射机制的优缺点及适用场景探讨Java中反射机制的优缺点及适用场景探讨Java中反射机制的优缺点及适用场景探讨Java中反射机制的优缺点及适用场景探讨

    反射是一种让程序在运行时动态获取类信息并操作类或对象的能力,它使程序能够检查、修改类的结构并调用其方法和属性。优势包括:1. 提供动态性与灵活性;2. 支持框架设计如spring的依赖注入;3. 实现插件系统的动态加载;4. 构建动态代理以执行额外操作;5. 开发通用工具处理各种类型对象。劣势有:1…

    2026年8月26日 用户投稿
    000
  • PCIe Riser 延长线对显卡性能的损耗实测

    使用合格的PCIe Riser延长线对显卡性能影响极小,实测显示性能损耗在1%-2%之间,帧数波动不超过1-2帧,基本处于误差范围内,实际体验无感知;即便是高端显卡如RTX 4090在PCIe 5.0平台搭配4.0延长线,数据传输速率和极限负载表现也无明显差异;选购时需注意版本匹配、供电连接可靠,并…

    2026年8月26日
    100
  • 告别PHP命令行参数混乱:nategood/commando助你打造优雅CLI工具!

    可以通过一下地址学习composer:学习地址 命令行工具开发的“痛点” 作为php开发者,我们经常需要编写一些命令行脚本来执行自动化任务、数据处理或系统维护。一开始,我们可能习惯于直接使用php内置的 $argv 超全局变量来获取命令行参数,或者尝试使用 getopt() 函数进行稍微结构化的解析…

    用户投稿 2026年8月26日
    000
  • 如何解决HEIC/AVIF图片转换难题?使用Composer和heif-converter轻松搞定!

    可以通过一下地址学习composer:学习地址 告别 HEIC/AVIF 图片兼容性烦恼:用 Composer 玩转 heif-converter 相信很多朋友都有过这样的经历:朋友用 iphone 拍了张照片发给你,结果你发现它是个 .heic 文件。或者,你在网上下载了一些高质量的图片,发现它们…

    用户投稿 2026年8月26日
    000
  • 电脑找不到vcruntime140_1.dll无法继续执行代码的解决方法

    电脑找不到vcruntime140_1.dll无法继续执行代码的解决方法电脑找不到vcruntime140_1.dll无法继续执行代码的解决方法电脑找不到vcruntime140_1.dll无法继续执行代码的解决方法电脑找不到vcruntime140_1.dll无法继续执行代码的解决方法

    打开某个软件或游戏时,突然提示“找不到vcruntime140_1.dll,无法继续执行代码”?这类错误通常源于系统缺少必要的运行库支持。接下来,我们一起来看看几种实用的解决方案。 一、为什么会提示“vcruntime140_1.dll缺失”? vcruntime140_1.dll 是微软 Visu…

    2026年8月26日 用户投稿
    000
  • Java中如何旋转图片 分析图像旋转的实现

    Java中如何旋转图片 分析图像旋转的实现Java中如何旋转图片 分析图像旋转的实现Java中如何旋转图片 分析图像旋转的实现Java中如何旋转图片 分析图像旋转的实现

    图像旋转通过坐标变换实现,核心步骤包括确定旋转中心、计算旋转矩阵、应用变换、处理边界及插值。旋转中心通常为图像中心,也可自定义;旋转矩阵描述二维空间中绕点逆时针旋转的数学关系;使用逆矩阵将目标像素映射回原始坐标;旋转后图像可能超出边界,需裁剪或填充;插值常用最近邻、双线性或双三次方法,其中双线性在速…

    2026年8月26日 用户投稿
    300
  • AI做文本校对怎么用_GrammarlyAI语法检查高级技巧

    AI校对是效率工具但不能替代人工,正确用法是将其作为助手。首先用Grammarly检查拼写、语法,再利用其风格一致性、上下文分析功能优化表达;结合自定义规则和主动学习提升匹配度。使用时需结合语境判断建议合理性,重点修改不确定内容,并积累常见错误经验。隐私方面要注意数据上传风险,敏感内容应选本地或开源…

    2026年8月26日
    000
  • 私信自动回复卡片违规吗?私信自动回复卡片违规吗安全吗

    随着社交媒体的普及,越来越多的人开始使用私信功能进行交流。近年来,一种名为“私信自动回复卡片”的现象在社交媒体上引起了广泛争议。这种自动回复卡片真的违规吗?本文将为您揭开这一谜团。 一、什么是私信自动回复卡片? 在社交媒体上,许多用户为了方便快捷地回复私信,会选择使用自动回复卡片。这种卡片通常包含一…

    2026年8月26日
    000
  • java中的var有什么用 类型推断var的4个使用限制

    java中的var有什么用 类型推断var的4个使用限制java中的var有什么用 类型推断var的4个使用限制java中的var有什么用 类型推断var的4个使用限制java中的var有什么用 类型推断var的4个使用限制

    java中的var关键字通过编译器推断变量类型,使代码更简洁,例如用var mymap = new hashmap<string, list>();代替冗长的类型声明。但其使用需注意4个限制:1. 必须初始化变量;2. 只能用于局部变量;3. 不能用于方法参数;4. 不能用于复合声明。此…

    2026年8月26日 用户投稿
    000
  • 如何优雅地管理PHP异步操作?GuzzlePromises与Composer助你告别回调地狱

    可以通过一下地址学习composer:学习地址 告别“回调地狱”:PHP异步编程的优雅之道 想象一下,你正在开发一个复杂的web服务,需要同时从多个外部api获取数据,或者执行一系列耗时的数据处理任务。如果你按照传统的同步方式编写代码,用户就得眼睁睁地看着页面转圈,直到所有操作完成。这显然不是一个好…

    用户投稿 2026年8月26日
    100
  • 自定义协程调度器的开发

    开发自定义协程调度器的原因包括对现有调度器不满意、特定性能需求或深入了解协程工作原理。实现步骤包括:1.理解协程基本概念,2.使用python的asyncio库创建自定义调度策略,3.管理协程状态和执行顺序。注意点有:1.协程状态管理,2.上下文切换效率,3.避免死锁和活锁,4.资源管理,5.调试和…

    2026年8月26日
    000
  • Java中如何填充颜色 掌握区域填充的实现

    Java中如何填充颜色 掌握区域填充的实现Java中如何填充颜色 掌握区域填充的实现Java中如何填充颜色 掌握区域填充的实现Java中如何填充颜色 掌握区域填充的实现

    在java中填充颜色,核心在于操作图像像素并使用java的图像处理api。1. 创建bufferedimage对象作为图像缓冲区;2. 通过creategraphics()获取graphics2d对象用于绘制;3. 使用setcolor()设置填充颜色;4. 调用fillrect()或fill()方…

    2026年8月26日 用户投稿
    000
  • 上市之路“一波三折”,京东工业离招股书再次失效仅剩4天!

    上市之路“一波三折”,京东工业离招股书再次失效仅剩4天!上市之路“一波三折”,京东工业离招股书再次失效仅剩4天!上市之路“一波三折”,京东工业离招股书再次失效仅剩4天!上市之路“一波三折”,京东工业离招股书再次失效仅剩4天!

    刘强东何时能收获第6家上市公司? 作者 | 郝文 编辑 | 趣解商业TMT组 “工业品界的京东”要上市了! 京东旗下的B2B采购平台“京东工业”,是专注于工业品供应链的服务商,它如同一个面向企业的“超级货仓”,从小小的螺丝螺母到大型专业设备,均可在上面一站式采购。 近日,证监会官网最新发布的备案通知…

    2026年8月26日 用户投稿
    000
  • 聊聊zfs中的write

    以下是关于zfs和zpool的伪原创内容,保持了原文的结构和大意,同时进行了改写: // 创建一个zpool$ modprobe zfs$ zpool create -f -m /sample sample -o ashift=12 /dev/sdc$ zfs create sample/fs1 -…

    2026年8月26日
    000
  • 大疆无人机怎么用后期处理_大疆无人机拍摄素材后期处理软件与流程

    使用大疆无人机航拍后,可通过DJI Mimo App快速剪辑并还原D-Log色彩,影忆实现全自动调色与AI字幕,DaVinci Resolve进行专业级调色优化,Photoshop合成AEB连拍HDR照片,Pix4Dmapper处理带POS信息的测绘影像,满足从短视频到专业建模的全流程需求。 如果您…

    2026年8月25日
    000
  • Java中collect方法怎么用 掌握流结果收集的各种方式

    Java中collect方法怎么用 掌握流结果收集的各种方式Java中collect方法怎么用 掌握流结果收集的各种方式Java中collect方法怎么用 掌握流结果收集的各种方式Java中collect方法怎么用 掌握流结果收集的各种方式

    java的collect方法是stream api中的终结操作,用于将流元素收集到指定数据结构中。其核心在于supplier、accumulator和combiner三个参数:1.supplier创建结果容器;2.accumulator将元素添加到容器;3.combiner合并多个容器结果。常用co…

    2026年8月25日 用户投稿
    000
  • 掌上高考志愿填报可靠吗

    掌上高考的准确性取决于数据来源与推荐逻辑透明度,其高校录取数据需核对是否来自教育部阳光高考平台或省级考试院,并对比目标院校官网公布的历年分数,偏差超5分应警惕;智能推荐功能须提供算法说明,明确使用位次法或线差法,纳入招生变动信息,且支持个性化调整,否则可信度受限。 如果您正在为高考志愿填报寻找可靠的…

    2026年8月25日
    200
  • 告别繁琐的对象映射:如何使用JoliCodeAutoMapper优化PHP开发效率

    最近在开发一个复杂的后端系统时,我遇到了一个反复出现的“痛点”:对象映射。想象一下这样的场景:你从前端接收一个 JSON 请求体,首先将其反序列化到一个 UserRequestDTO 对象。然而,你的业务逻辑和数据库操作需要的是一个 User 领域实体。这意味着你需要手动编写大量的代码,将 User…

    用户投稿 2026年8月25日
    000
  • 安装错误0x80070002怎么解决 0x80070002错误代码解决

    安装错误0x80070002怎么解决 0x80070002错误代码解决安装错误0x80070002怎么解决 0x80070002错误代码解决安装错误0x80070002怎么解决 0x80070002错误代码解决安装错误0x80070002怎么解决 0x80070002错误代码解决

    在安装windows更新或部分软件时,不少用户会遭遇“错误代码:0x80070002”的提示。该问题在win7、win10乃至win11系统中均有发生,一旦出现,安装流程将被迫中断,导致更新或程序无法正常完成。为帮助大家高效应对这一故障,请跟随以下步骤逐一排查并解决。 一、问题成因梳理 错误代码 0…

    2026年8月25日 用户投稿
    100
  • 如何解决Magento2图片加载慢的问题,使用Composer和WebP模块让你的电商网站飞起来

    Composer在线学习地址:学习地址 痛点:电商网站的“甜蜜负担”——图片 在电商领域,高质量的产品图片是吸引顾客、促成转化的关键。然而,这些精美的图片也常常成为网站性能的“甜蜜负担”。当用户访问一个图片众多的商品列表页或详情页时,浏览器需要下载大量的图片资源,这直接导致页面加载时间过长。 我曾在…

    用户投稿 2026年8月25日
    000

发表回复

登录后才能评论
关注微信