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

迁移至Java 17+Jakarta库后,Jackson无法反序列化含私有构造方法的类

问题分析与解决方案

核心问题拆解

  1. 库依赖变更:迁移到Jakarta后,你的项目实际使用的是Yasson(Jakarta JSON-B官方实现),而非原来的Jackson——这也是Jackson的@JsonCreator注解失效的原因,Yasson不识别Jackson的注解。
  2. Java17反射限制:Java17收紧了反射访问权限,外部类默认无法通过反射调用私有构造方法,即使是序列化库也不行。

针对性解决方案

方案1:用JSON-B注解标记私有构造

给Application类的私有构造添加Yasson(JSON-B)专属的@JsonbCreator注解:

import jakarta.json.bind.annotation.JsonbCreator;

public class Application {
    // 给私有构造添加JSON-B的创建注解
    @JsonbCreator
    private Application() {
        // 你的构造逻辑
    }

    // 其他字段、getter/setter等
}

如果是带参数的私有构造,还需要配合@JsonbProperty指定字段映射:

@JsonbCreator
private Application(@JsonbProperty("name") String name) {
    this.name = name;
}

方案2:配置Yasson开放非公共成员访问

通过JsonbConfig全局设置允许访问类的所有成员(包括私有):

import jakarta.json.bind.Jsonb;
import jakarta.json.bind.JsonbBuilder;
import jakarta.json.bind.JsonbConfig;
import jakarta.json.bind.accessor.AccessMode;

// 创建配置,开放所有成员访问权限
JsonbConfig config = new JsonbConfig()
    .withProperty(JsonbConfig.PROPERTY_ACCESS_MODE, AccessMode.ALL);
// 用配置初始化Jsonb实例
Jsonb jsonb = JsonbBuilder.create(config);
// 反序列化
Application app = jsonb.fromJson(yourJsonString, Application.class);

方案3:模块权限配置(若使用Java模块系统)

如果你的项目是模块化项目(存在module-info.java),需要给Yasson模块开放反射访问权限:

module your.project.module {
    // 允许Yasson反射访问a.b.c.d包下的类
    opens a.b.c.d to org.eclipse.yasson;
}

方案4:换回Jakarta版本的Jackson(如果想继续用Jackson)

如果你更习惯用Jackson,需要引入支持Jakarta的Jackson依赖(比如最新的2.15+版本),然后:

  • 确保使用Jackson的@JsonCreator注解(com.fasterxml.jackson.annotation.JsonCreator)
  • 配置ObjectMapper开放私有构造的访问权限:
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonAutoDetect;

ObjectMapper mapper = new ObjectMapper();
// 设置允许Jackson访问私有构造、字段
mapper.setVisibility(mapper.getSerializationConfig().getDefaultVisibilityChecker()
    .withCreatorVisibility(JsonAutoDetect.Visibility.ANY)
    .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
    .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
    .withSetterVisibility(JsonAutoDetect.Visibility.NONE));
// 反序列化
Application app = mapper.readValue(yourJsonString, Application.class);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:35:19