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

