@JsonProperty 用于构造方法和属性

@JsonProperty 是 Jackson 库中的注解,用于指定 JSON 数据与 Java 对象之间的映射。它可以用在构造方法参数类属性上,但两者的行为和使用场景有所不同。


1. @JsonProperty 用在构造方法参数上

@JsonProperty 用在构造方法参数上时,Jackson 会使用该构造方法来反序列化 JSON 数据到 Java 对象。它会根据 JSON 数据中的字段名称匹配构造方法参数上的 @JsonProperty 注解。

特点:

  • 构造方法驱动的反序列化 :Jackson 会根据 JSON 数据调用带有 @JsonProperty 注解的构造方法来创建对象。
  • 不可变对象支持 :适用于不可变对象(final 属性)的场景,因为属性只能通过构造方法赋值。
  • 更安全的初始化:所有属性在对象创建时就被初始化,避免了后续的 setter 方法调用。

示例:

java 复制代码
public class UserInfo {
    private final String userType;
    private final PhoneNumber phoneNumber;

    public UserInfo(@JsonProperty("userType") final String userType,
                    @JsonProperty("phoneNumber") final PhoneNumber phoneNumber) {
        this.userType = userType;
        this.phoneNumber = phoneNumber;
    }
}

JSON 数据

java 复制代码
{
  "userType": "admin",
  "phoneNumber": {
    "countryCode": "+1",
    "number": "1234567890"
  }
}

反序列化过程

  • Jackson 会解析 JSON 数据,并根据 @JsonProperty 注解找到对应的构造方法参数。
  • 调用构造方法 UserInfo(String userType, PhoneNumber phoneNumber, String nuId) 创建对象。

2. @JsonProperty 用在属性上

@JsonProperty 用在类属性上时,Jackson 会通过默认的无参构造方法创建对象,然后通过反射调用属性的 setter 方法(或直接访问字段)来设置值。

特点:

  • 基于默认构造方法的反序列化:需要类有一个无参构造方法(如果没有显式定义,Java 会提供一个默认的无参构造方法)。
  • 支持可变对象:适用于需要通过 setter 方法或直接修改属性值的场景。
  • 更灵活的映射:可以直接在属性上定义 JSON 字段名称,避免在构造方法中显式声明。

示例:

java 复制代码
public class UserInfo {
    @JsonProperty("userType")
    private String userType;

    @JsonProperty("phoneNumber")
    private PhoneNumber phoneNumber;

    // 无参构造方法
    public UserInfo() {}

    // Getters and Setters
}

JSON 数据

java 复制代码
{
  "userType": "admin",
  "phoneNumber": {
    "countryCode": "+1",
    "number": "1234567890"
  }
}

反序列化过程

  • Jackson 会调用无参构造方法创建 UserInfo 对象。
  • 根据 @JsonProperty 注解找到对应的 JSON 字段,并通过反射设置属性值。

3. 两者的主要区别

特性 用在构造方法参数上 用在属性上
对象创建方式 使用带注解的构造方法创建对象 使用无参构造方法创建对象
适用场景 不可变对象(final 属性) 可变对象
依赖的构造方法 必须有带 @JsonProperty 注解的构造方法 必须有无参构造方法
灵活性 需要在构造方法中定义所有需要的属性 可以在类中定义部分或全部属性
性能 构造方法反序列化性能稍高(少一次反射调用) 通过反射设置属性,性能稍低
代码风格 更适合不可变对象和构造方法初始化的场景 更适合传统的 Java Bean 风格

4. 如何选择

  • 使用构造方法参数上的 @JsonProperty

    • 如果类是不可变的(final 属性)。
    • 如果希望在对象创建时就完成所有属性的初始化。
    • 如果类没有无参构造方法,或者不希望提供无参构造方法。
  • 使用属性上的 @JsonProperty

    • 如果类是可变的(需要 setter 方法或直接修改属性)。
    • 如果需要更灵活的 JSON 映射。
    • 如果类需要与传统的 Java Bean 风格兼容。

5. 总结

  • 构造方法上的 @JsonProperty 更适合不可变对象,确保对象在创建时就被完全初始化。
  • 属性上的 @JsonProperty 更适合可变对象,提供更灵活的映射方式。
相关推荐
QQ_21696290963 分钟前
Spring Boot 养老院管理系统:从入住、护理到费用结算的全流程实现(源码可领)
java·spring boot·后端
cxoptics20 分钟前
冰洲石分束器设计与应用
java
ck-joker35 分钟前
M1 Pro跑LLM实测:Ollama+LangChain4j零成本本地大模型开发,比云端API快在哪?
java·语言模型
丙氨酸長鏈1 小时前
[Bukkit插件开发]手持发射器箭矢机枪 教学文档 面向Python/C#开发者入门Java与Bukkit API
java·python·c#
Nontee1 小时前
设计模式:模板方法与策略,从“每个字都认识“到能说清它们在干嘛
java·数据库·设计模式
我是唐青枫1 小时前
Java ReentrantLock 实战详解:比 synchronized 更灵活的可重入锁
java·开发语言
晨曦中的暮雨2 小时前
Virtual Thread 优化 Spring AI 阻塞式 LLM I/O:对照压测报告
java·并发·个人项目
AKA__Zas3 小时前
芝士算法(前缀和2.0)
java·数据结构·算法·leetcode·哈希算法·学习方法
caishenzhibiao3 小时前
降雨带波段点差 同花顺期货通指标
java·c语言·c#
七夜zippoe3 小时前
OpenClaw Prompt 工程:从角色设定到 Skill 封装的 Agent 输出质量方法论
java·服务器·prompt·openclaw·skill封装