You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gson自定义布尔反序列化器失效问题排查

Why isn't my custom Boolean deserializer working in Gson?

Great question! The issue here boils down to Gson's internal priority system for type adapters. Let me break down what's happening and how to fix it:

What's causing the problem?

Gson has built-in TypeAdapter implementations for common Java/Kotlin types like Boolean (and its primitive boolean counterpart). These built-in adapters take higher priority than any JsonDeserializer you register via GsonBuilder.registerTypeAdapter().

When you try to parse {"value": 0}, Gson uses its default Boolean adapter, which only recognizes the literal true/false values. It doesn't handle numeric 0/1, hence the JsonSyntaxException you're seeing.

Your enum deserializers work because Gson's built-in enum handling doesn't have the same priority lock—custom JsonDeserializers can override it without issue.

How to fix it: Use a TypeAdapter instead

To get your numeric-to-boolean logic working, you need to replace Gson's built-in Boolean adapter entirely by implementing a TypeAdapter<Boolean?> instead of a JsonDeserializer. Here's how to do it in Kotlin:

Step 1: Create the custom TypeAdapter

import com.google.gson.TypeAdapter
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonToken
import com.google.gson.stream.JsonWriter

class IntBooleanTypeAdapter : TypeAdapter<Boolean?>() {
    override fun write(out: JsonWriter, value: Boolean?) {
        // Handle serialization (if needed)
        out.value(value ?: false)
    }

    override fun read(`in`: JsonReader): Boolean? {
        return when (`in`.peek()) {
            // Convert numbers 0 → false, 1 → true
            JsonToken.NUMBER -> `in`.nextInt() == 1
            // Keep regular boolean values working
            JsonToken.BOOLEAN -> `in`.nextBoolean()
            // Handle null for nullable Boolean?
            JsonToken.NULL -> {
                `in`.nextNull()
                null
            }
            // Throw an error for unexpected token types
            else -> throw JsonSyntaxException("Expected boolean or number, but was ${`in`.peek()}")
        }
    }
}

Step 2: Register the adapter correctly

Make sure to register it for both the nullable Boolean class and the primitive boolean type (to cover all use cases):

import com.google.gson.GsonBuilder

val gson = GsonBuilder()
    .registerTypeAdapter(Boolean::class.java, IntBooleanTypeAdapter())
    .registerTypeAdapter(Boolean::class.javaPrimitiveType, IntBooleanTypeAdapter())
    .create()

Step 3: Test it out

Your original test code will now work as expected:

data class BooleanClass(val value: Boolean?)

fun main() {
    val objZero = gson.fromJson("{\"value\": 0}", BooleanClass::class.java)
    println(objZero.value) // Prints false

    val objOne = gson.fromJson("{\"value\": 1}", BooleanClass::class.java)
    println(objOne.value) // Prints true

    val objTrue = gson.fromJson("{\"value\": true}", BooleanClass::class.java)
    println(objTrue.value) // Prints true

    val objNull = gson.fromJson("{\"value\": null}", BooleanClass::class.java)
    println(objNull.value) // Prints null
}

Why this works

By using a TypeAdapter, you're directly replacing Gson's built-in adapter for Boolean types. TypeAdapters are at the top of Gson's priority chain for type handling, so your custom logic will be used instead of the default one.

内容的提问来源于stack exchange,提问作者artem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 10:07:40