JSON 转 Kotlin 数据类
从 JSON 生成 kotlinx.serialization 用的 Kotlin data class:自带 import,按数值选 Int / Long / Double,类型不确定时用 JsonElement,支持嵌套对象。在浏览器中运行。
- 在浏览器中处理
- 数据不离开你的设备
- 免费 · 无需注册
用微信扫描以下二维码即可分享
示例、说明与常见问题 带实际输出的示例、与同类工具的差别,以及常见问题。
类型映射
- 字符串 →
String;布尔 →Boolean - −2,147,483,648 到 2,147,483,647 的整数 →
Int;更大 →Long;超出Long范围 →Double - 写有小数点或指数的数字(
9.5、19.0、1e3)→Double - 数组 →
List<T>;Int、Long、Double混合时取最宽的类型;其他混合与空数组 →List<JsonElement> null→ 可空类型;始终为null的字段 →JsonElement?- 嵌套对象 → 独立的
data class;空对象{}→class Name(data class 至少要有一个属性)
示例:snake_case 的 API 响应
输入含 snake_case 键、一个 null 字段、一个超过 Int.MAX_VALUE 的计数和写成 4.0 的评分:
{"user_id": 1024, "display_name": "Alice", "is_active": true, "last_login": null, "follower_count": 3000000000, "rating": 4.0, "tags": ["admin", "editor"], "address": {"city": "Tokyo", "zip_code": "100-0001"}}
输出:
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement
@Serializable
data class RootObject(
@SerialName("user_id")
val userId: Int = 0,
@SerialName("display_name")
val displayName: String = "",
@SerialName("is_active")
val isActive: Boolean = false,
@SerialName("last_login")
val lastLogin: JsonElement? = null,
@SerialName("follower_count")
val followerCount: Long = 0L,
val rating: Double = 0.0,
val tags: List<String> = emptyList(),
val address: Address = Address()
)
@Serializable
data class Address(
val city: String = "",
@SerialName("zip_code")
val zipCode: String = ""
)
camelCase 名与 JSON 键不同的字段用 @SerialName 保留原键。用作键的 Kotlin 关键字(class、in、fun)会加反引号。last_login 在样本里只有 null,所以是 JsonElement?;确认它是时间戳后改成 String?。
示例:对象数组
根是数组时,所有对象合并为一个类。price 一个是 2、一个是 1.5,合并为 Double。部分元素缺少的键可空,默认 null:
[{"id": 1, "name": "Pen", "price": 2}, {"id": 2, "name": "Ink", "price": 1.5, "discount": 0.1}]
import kotlinx.serialization.Serializable
@Serializable
data class RootObject(
val id: Int = 0,
val name: String = "",
val price: Double = 0.0,
val discount: Double? = null
)
状态栏会提示按 List<RootObject> 解码。
示例:同名键、不同对象
两个名为 meta、字段不同的嵌套对象会生成两个类,第二个以父级名为前缀:
{"order": {"id": 7, "meta": {"source": "web"}}, "payment": {"meta": {"method": "card", "last4": "4242"}}}
import kotlinx.serialization.Serializable
@Serializable
data class RootObject(
val order: Order = Order(),
val payment: Payment = Payment()
)
@Serializable
data class Order(
val id: Int = 0,
val meta: Meta = Meta()
)
@Serializable
data class Meta(
val source: String = ""
)
@Serializable
data class Payment(
val meta: PaymentMeta = PaymentMeta()
)
@Serializable
data class PaymentMeta(
val method: String = "",
val last4: String = ""
)
解码
在构建配置里加入序列化插件和 JSON 库(见 Kotlin 序列化指南),然后解码:
import kotlinx.serialization.json.Json
val user = Json.decodeFromString<RootObject>(body)
val items = Json.decodeFromString<List<RootObject>>(arrayBody)
// 允许样本里没有的键
val lenient = Json { ignoreUnknownKeys = true }
默认的 Json 遇到类里没有的键会报错。本页所有示例都用 Kotlin 2.4.20 与 kotlinx.serialization 1.11.0 编译,并用默认配置解码通过。
限制
- 类型只看一份样本。样本里较小的 ID 会生成
Int,生产环境的 ID 若超过 2,147,483,647,需要自己改成Long。 - 浏览器按 64 位浮点数解析 JSON 数字,大于 9,007,199,254,740,991 的整数在判断类型前就丢了精度。类型仍为
Long,范围需要自己核对。 - 只有向
JSON.parse提供源文本的浏览器(Chrome 114+、Firefox 135+、Safari 18.4+)能把19.0识别为小数,旧浏览器会生成Int。 JsonElement字段只适用于Json格式,不适用于 CBOR、ProtoBuf。- 日期保持
String。JSON 没有日期类型,解码后自行解析或加自定义序列化器。 - 每个属性都有默认值,缺少的键会静默解码成默认值。必须出现的键请删掉默认值。
FAQ
这个工具生成什么?
生成带 @Serializable 注解的 Kotlin data class(kotlinx.serialization)以及所需的 import。每个嵌套对象生成一个独立的类。输出在启用 kotlinx.serialization 编译器插件后可以直接编译,并能用默认的 Json 配置解码样本。
可空字段怎么处理?
JSON 值为 null 的字段在 Kotlin 中标为可空(如 String?)。数组里部分元素缺少的字段同样可空,默认值为 null。样本里始终为 null 的字段生成 JsonElement?,因为样本看不出它的真实类型。
各类型的默认值是什么?
String 为 "",Int 为 0,Long 为 0L,Double 为 0.0,Boolean 为 false,List 为 emptyList(),JsonElement 为 JsonNull,可空类型为 null,嵌套类调用无参构造。有默认值时缺少的键可以正常解码。
为什么用 JsonElement 而不用 Any?
kotlinx.serialization 没有 Any 的序列化器,带 Any 字段的 @Serializable 类无法编译。JsonElement 是该库为任意形状的 JSON 提供的类型,用于始终为 null 的字段、空数组以及在样本间类型不同的值。
数据会发送到服务器吗?
不会。转换在浏览器中进行,数据不会离开你的设备。