fastjson2 icon indicating copy to clipboard operation
fastjson2 copied to clipboard

[BUG] 泛型嵌套时 `JSON.parseObject` 解析类型错误

Open EmptyDreams opened this issue 8 months ago • 0 comments

问题描述

当泛型嵌套使用时,使用 JSON.parseObject 搭配 TypeReference 解析 JSON 时忽略错误地泛型信息。

但是这个问题我无法在其它位置复现,我把代码复制出来之后,虽然代码一模一样,但是执行出来的结果就不一样了。

环境信息

请填写以下信息:

  • OS信息:Mac OS Sequoia 15.3.1 (2.6 GHz 六核Intel Core i7 + 16G)
  • JDK信息:Graalvm 21.0.6
  • 版本信息:Fastjson2 2.0.57

重现步骤

  1. 执行 test 方法
  2. 观察 obj 的值
fun test() {
//    if (event.type === CoreLifeCycleEnum.AFTER_INIT) {
        val text = "{\"data\":{\"outputs\":{\"errno\":0,\"data\":\"test\",\"msg\":\"ok\"}}}"
        val type = TypeReference.parametricType(
            DifyResponseBody::class.java,
            DifyDocBuilder::class.java
        )
        val obj = JSON.parseObject<DifyResponseBody<DifyDocBuilder>>(text, type)
        // 这里 `obj.data.outputs` 的类型是 `JSONObject`,实际应当是 DifyDocBuilder`。
        println(obj)
//    }
}

data class DifyResponseBody<T : Any>(
    val data: DifyResponseData<T>,
)

data class DifyResponseData<T : Any>(
    val outputs: T,
)

data class DifyDocBuilder(
    val errno: Int,
    val msg: String,
    val data: String?,
)

在调用 JSON.parseObject 中,在下图的位置,outputs的类型还是正确的:

图1.1

图1.2

但是在执行 creatorFunction.apply 时,出现了问题,paramType 的泛型参数变成了 T,然后 outputs 就被 cast 转换为了 JSONObject

图2.1

图2.2

我把我的代码单独拿出来跑到时候,并没有进入到 ObjectReaderNoneDefaultConstructor 这个类中执行,而是动态生成了一个类来解析 json,结果是正确的。

EmptyDreams avatar Apr 14 '25 05:04 EmptyDreams