当前位置:网站首页>@ConstructorProperties注解理解以及其对应使用方式
@ConstructorProperties注解理解以及其对应使用方式
2022-07-26 06:23:00 【搏·梦】
文章目录
1. 先说结论
@ConstructorProperties注解并不是json里面的,而是jdk自身携带的类。

当一个类有多个构造函数,在进行json转化成对象的时候,需要指定其使用那个构造函数时,可以使用@ConstructorProperties注解,告诉json转化过程中,使用哪个构造函数进行反序列化为对象。
默认不加任何其他条件情况下,json使用构造函数反序列化为对象时:
- 若有无参构造函数,以及有参构造函数时,优先会选择无参构造函数反序列化。
- 若有多个有参构造函数的情况下,但没有无参构造函数,优先会选择最多参数的有参构造函数反序列化。
- 上述两种情况,若新增条件@ConstructorProperties注解的话,优先选择被该注解的构造函数反序列化。
@ConstructorProperties一个注解 可以替代 json注解中的@JsonCreator与@JsonProperty同时使用的情况。
在springboot中使用@ConstructorProperties注解,其注解本身参数的功能完全失效,该注解的作用只剩:告诉ObjectMapper使用那个构造函数进行反序列化,原因尚未查明。
2. 快速入门使用
1. @JsonCreator与@JsonProperty的使用
@JsonCreator 指定使用那个构造函数进行反序列化。
@JsonProperty 指定json对象字段名字,与具体属性名字的对应关系。
代码如下:
@ToString public class AA { private String name; private String password; public AA(String name){ System.out.println("使用只有一个参数的构造函数"); this.name = name; } // 指定使用该构造函数进行反序列化 // @JsonProperty("pwd") 指名,属性password 与json的pwd字段对应 @JsonCreator public AA(@JsonProperty("name") String name, @JsonProperty("pwd") String password) { System.out.println("使用了全参构造函数哦"); this.name = name; this.password = password; } }public class demo { public static void main(String[] args) throws Exception{ String jsonStr = "{\n" + " \"name\":\"1\",\n" + " \"pwd\":\"123\"\n" + "}"; ObjectMapper objectMapper = new ObjectMapper(); final AA aa = objectMapper.readValue(jsonStr, AA.class); System.out.println(aa); } }
2. @ConstructorProperties使用
@ConstructorProperties 完全可以替代 @JsonCreator与@JsonProperty。
注解参数是指定json字段,与 构造函数 参数的对应,绑定关系。
代码如下:
@ToString public class AA { private String name; private String password; public AA(String name){ System.out.println("使用只有一个参数的构造函数"); this.name = name; } // 该注解参数是指定json字段,与 构造函数 参数的对应 // 将属性password 与json的pwd字段对应 // 将属性namee 与json的name字段对应 @ConstructorProperties({ "name", "pwd"}) public AA(String name, String password) { System.out.println("使用了全参构造函数哦"); this.name = name; this.password = password; } }public class demo { public static void main(String[] args) throws Exception{ String jsonStr = "{\n" + " \"name\":\"1\",\n" + " \"pwd\":\"123\"\n" + "}"; ObjectMapper objectMapper = new ObjectMapper(); final AA aa = objectMapper.readValue(jsonStr, AA.class); System.out.println(aa); } }
该@ConstructorProperties注解参数是指定json字段,与 构造函数 参数的对应
将代码改成@ConstructorProperties({“pwd”, “name”})@ToString public class AA { private String name; private String password; public AA(String name) { System.out.println("使用只有一个参数的构造函数"); this.name = name; } // 故意将 对应关系写反 // 因此这里的绑定关系是: // json的pwd 对应 name // json的name 对应 password @ConstructorProperties({ "pwd", "name"}) public AA(String name, String password) { System.out.println("使用了全参构造函数哦"); this.name = name; this.password = password; } } public class demo { public static void main(String[] args) throws Exception{ String jsonStr = "{\n" + " \"pwd\":\"123\",\n" + " \"name\":\"1\"\n" + "}"; ObjectMapper objectMapper = new ObjectMapper(); final AA aa = objectMapper.readValue(jsonStr, AA.class); System.out.println(aa); } }
由上图可知,原本name=1,现在则是name=123
3. 验证结论
1. 前言准备
下面的ObjectMapper,都是基于ObjectMapper,毕竟其是springboot默认使用的json转化工具。
准备一个实体类,一个controller层:
@ToString public class AA { private String name; private String password; public AA(String name){ System.out.println("使用只有一个参数的构造函数"); this.name = name; } public AA(String name, String password) { System.out.println("使用了全参构造函数哦"); this.name = name; this.password = password; } public AA(){ System.out.println("使用无参构造函数"); } } @RestController public class ConstructorTestController { @PostMapping("/test/A") public void testA(@RequestBody AA a){ System.out.println(a); } }在AA实体类上,只加@ToString方法,为了方便查看其属性的赋值,这里并不能增加@Getter或者@Setter注解,因为json在转化也可以基于这两个方法进行,具体可以查阅:(ObjectMapper)Json转化对象的基本原理
基于上述第三点,做个小科普,json的转化使用方式的优先级是:set方法、public的field属性、get方法、构造函数。
2. 验证无参构造与有参构造同时存在情况
无参构造与有参构造同时存在,优先级是无参构造函数:

若此时使用 @ConstructorProperties({“name”, “password”}),优先级则是被注解指定的构造函数
@ToString public class AA { private String name; private String password; public AA(String name) { System.out.println("使用只有一个参数的构造函数"); this.name = name; } @ConstructorProperties({ "name", "password"}) public AA(String name, String password) { System.out.println("使用了全参构造函数哦"); this.name = name; this.password = password; } public AA() { System.out.println("使用无参构造函数"); } }
3. 验证只有 有参构造函数情况
当只有有参构造函数,无加其他任何注解,优先级则是参数最多的构造函数进行反序列化。
代码如下:
@ToString public class AA { private String name; private String password; public AA(String name) { System.out.println("使用只有一个参数的构造函数"); this.name = name; } public AA(String name, String password) { System.out.println("使用了全参构造函数哦"); this.name = name; this.password = password; } }
有的人可能会说,因为刚刚好json有两个字段,所有才使用了全参的构造函数,现我们改成只有name字段的json请求:

由上可知,优先级:则是最多参数的构造函数当我们使用@ConstructorProperties注解,注解参数写上 name,password


或者注解参数只写上name

4. 在springboot中使用@ConstructorProperties注解时,参数功能完全失效
在快速入门中,我们提及到@ConstructorProperties注解的参数,是将json字段与自身构造函数的参数进行对应
但经测试,在springboot中,似乎并不是这样子,代码如下:
对应关系为:json的字段pwd 对应 属性name,json的字段name对应属性password@ToString public class AA { private String name; private String password; public AA(String name) { System.out.println("使用只有一个参数的构造函数"); this.name = name; } @ConstructorProperties({ "pwd", "name"}) public AA(String name, String password) { System.out.println("使用了全参构造函数哦"); this.name = name; this.password = password; } }

边栏推荐
- 【Day_03 0420】字符串中找出连续最长的数字串
- YOLOv7: Trainable bag-of-freebies sets new state-of-the-art for real-time object detectors
- [day_060423] convert string to integer
- Matlab vector and matrix
- [day_010418] delete public string
- Widget is everything, widget introduction
- Using dynamic libraries in VS
- [day_030420] find the longest consecutive number string in the string
- Introduction to three feasible schemes of grammatical generalization
- Webapi collation
猜你喜欢

PG Vacuum 杂谈之 auto vacuum

Registration conditions for system integration project management engineer (intermediate level of soft exam) in the second half of 2022

【无标题】
![[day05_0422] C language multiple choice questions](/img/cb/0019ec819480bd9f52055e726b323a.png)
[day05_0422] C language multiple choice questions

Matlab vector and matrix

【Day04_0421】C语言选择题

Age is a hard threshold! 42 years old, Tencent level 13, master of 985, looking for a job for three months, no company actually accepted!

Cdga | how to build data asset catalogue?

redis 哨兵集群搭建

Sequential action localization | fine grained temporal contrast learning for weak supervised temporal action localization (CVPR 2022)
随机推荐
Embedded sharing collection 15
Redis sentinel cluster setup
【Day_01 0418】删除公共字符串
What is KVM? What is KVM virtual machine?
Jz36 binary search tree and bidirectional linked list
Leetcode:934. The shortest Bridge
移动web
ament_ Cmake generates the ros2 library and links it
Ganglia installation and deployment process
C language explanation series - comprehensive exercises, guessing numbers games
Map collection inheritance structure
【Day_07 0425】合法括号序列判断
Map集合继承结构
Upgrade appium automation framework to the latest 2.0
A tool for quickly switching local host files -- switchhosts
English sentence pattern reference exclusive Edition - attributive clause
英语句式参考纯享版 - 定语从句
[day_060423] convert string to integer
RNN循环神经网络
English sentence pattern reference exclusive Edition - adverbial clause