有时,一张表里面存储的具体对象可能不一样,比如Person表,里面我存了man和woman,除去共有属性如姓名,年龄,性别等,可能还有一些属性不一样,针对man,woman又有不同的其他业务处理等,此时,新增或者修改接口我们都是用的同一个,如果传一个具体的对象避免不了要做各种判断逻辑,代码太冗余,那如何直接传顶层的抽象类(Person)呢?这就涉及到了一个多态的处理~ 这就是本文的主角Jackson框架
jackson允许配置多态类型处理,当进行反序列话时,JSON数据匹配的对象可能有多个子类型,为了正确的读取对象的类型,我们需要添加一些类型信息。可以通过下面几个注解来实现:
@JsonTypeInfo
作用于类/接口,被用来开启多态类型处理,对基类/接口和子类/实现类都有效
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "partner", visible = true, defaultImpl = Man.class)
属性介绍:
-
use
:定义使用哪一种类型识别码,它有下面几个可选值:
-
JsonTypeInfo.Id.CLASS
:使用完全限定类名做识别
-
JsonTypeInfo.Id.MINIMAL_CLASS
:若基类和子类在同一包类,使用类名(忽略包名)作为识别码
-
JsonTypeInfo.Id.NAME
:一个合乎逻辑的指定名称
-
JsonTypeInfo.Id.CUSTOM
:自定义识别码,由
@JsonTypeIdResolver
对应,稍后解释
-
JsonTypeInfo.Id.NONE
:不使用识别码
-
include
(可选):指定识别码是如何被包含进去的,它有下面几个可选值:
-
JsonTypeInfo.As.PROPERTY:作为数据的兄弟属性(默认)
-
JsonTypeInfo.As.EXISTING_PROPERTY:作为POJO中已经存在的属性
-
JsonTypeInfo.As.EXTERNAL_PROPERTY:作为扩展属性
-
JsonTypeInfo.As.WRAPPER_OBJECT:作为一个包装的对象
-
JsonTypeInfo.As.WRAPPER_ARRAY:作为一个包装的数组
-
property
(可选):制定识别码的属性名称
此属性只有当:
-
use
为
JsonTypeInfo.Id.CLASS
(若不指定property则默认为
@class
)、
JsonTypeInfo.Id.MINIMAL_CLASS
(若不指定property则默认为
@c
)、
JsonTypeInfo.Id.NAME
(若不指定property默认为
@type
),
-
include
为
JsonTypeInfo.As.PROPERTY
、
JsonTypeInfo.As.EXISTING_PROPERTY
、
JsonTypeInfo.As.EXTERNAL_PROPERTY
时才有效
-
defaultImpl
(可选):如果类型识别码不存在或者无效,可以使用该属性来制定反序列化时使用的默认类型
-
visible
(可选,默认为false):是否可见
属性定义了类型标识符的值是否会通过JSON流成为反序列化器的一部分,默认为fale,也就是说,jackson会从JSON内容中处理和删除类型标识符再传递给JsonDeserializer。
@JsonSubTypes
作用于类/接口,用来列出给定类的子类,只有当子类类型无法被检测到时才会使用它,一般是配合@JsonTypeInfo在基类上使用,比如:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "partner", visible = true, defaultImpl = Man.class)
@JsonSubTypes({
@JsonSubTypes.Type(value = Man.class, name = "wife"),
@JsonSubTypes.Type(value = Woman.class, name = "husband")
@JsonTypeName
作用于子类,用来为多态子类指定类型标识符的值,使用该注解则可以不使用@JsonSubTypes
比如:
@JsonTypeName("husband")
public class Woman extends Person {...}
@JsonTypeName("wife")
public class Man extends Person {...}
demo:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.13.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.3</version>
</dependency>
package com.cjian.jackson;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
* @Author: cjian
* @Date: 2022/6/27 10:42
* @Des:
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "partner", visible = true, defaultImpl = Man.class)
@JsonSubTypes({
@JsonSubTypes.Type(value = Man.class, name = "wife"),
@JsonSubTypes.Type(value = Woman.class, name = "husband")
public abstract class Person {
private String name;
private int age;
private String sex;
private String partner;
public String getName() {
return name;
public void setName(String name) {
this.name = name;
public int getAge() {
return age;
public void setAge(int age) {
this.age = age;
public String getSex() {
return sex;
public void setSex(String sex) {
this.sex = sex;
public String getPartner() {
return partner;
public void setPartner(String partner) {
this.partner = partner;
两个子类:
package com.cjian.jackson;
import com.fasterxml.jackson.annotation.JsonTypeName;
* @Author: cjian
* @Date: 2022/6/27 10:44
* @Des:
public class Man extends Person {
private String wife;
public String getWife() {
return wife;
public void setWife(String wife) {
this.wife = wife;
@Override
public String toString() {
return "Man{" +
"wife='" + wife + '\'' +
package com.cjian.jackson;
import com.fasterxml.jackson.annotation.JsonTypeName;
* @Author: cjian
* @Date: 2022/6/27 10:43
* @Des:
public class Woman extends Person {
private String husband;
public String getHusband() {
return husband;
public void setHusband(String husband) {
this.husband = husband;
@Override
public String toString() {
return "Woman{" +
"husband='" + husband + '\'' +
package com.cjian.jackson;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
* @Author: cjian
* @Date: 2022/6/29 10:30
* @Des:
public class Test {
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
String jsonString1 = "{\"name\":\"cjian\",\"age\":28,\"sex\":\"男\",\"partner\":\"wife\",\"wife\":\"lili\"}";
String jsonString2 = "{\"name\":\"lili\",\"age\":28,\"sex\":\"女\",\"partner\":\"husband\",\"husband\":\"cjian\"}";
Person p1 = objectMapper.readValue(jsonString1, Man.class);
Person p2 = objectMapper.readValue(jsonString2, Woman.class);
System.out.println(p1);
System.out.println(p2);
一、问题背景
Jackson的对json字段的序列化和反序列化默认策略是根据getter和setter方法,去掉get和set,再把首字母小写,便找到了对应的字段。通常情况,我们都是对普通的POJO进行serialization/deserialization。那么如果遇到了解析抽象类呢?如何定位到对应的实现类?实现类都找不到,谈何匹配到对应的字段反序列化。
二、JsonTypeInfo 注解...
让我们看Jackson控制多态的注解:
@JsonTypeInfo – indicates details of what type information to include in serialization 指出序列化包含的类型信息细节
@JsonSubTypes – indicates sub-types of the annotated type 指出被注解类型的子类
...
import com.fasterxml.jackson.annotation.JacksonAnnotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang...
博主github
博主个人博客http://blog.healerjean.com
Jackson允许配置多态类型处理,当进行反序列话时,Json数据匹配的对象可能有多个子类型,为了正确的读取对象的类型,我们需要添加一些类型信息。
1.1、@JsonTypeInfo
@JsonTypeInfo这个注解可以直接放在类上,也可以放在某个属性上:下面是内部的属性值
1.1.1、use: ...
一、Jackson之序列化和反序列化
JSON作为一种轻量级的数据交换格式,其清晰和简洁的结构能够轻松地与Java对象产生映射关系。Java开发中常常使用Jackson对JSON文本格式进行序列化和反序列化:
序列化:是指将Java对象转换成Json文件或者Json字符串;
反序列化:是指将Json文件或者Json字符串转换成Java对象。
例如,有如下定义的java的bean:
public cl.
@JsonTypeInfo 逻辑名称 @JsonSubTypes、@JsonTypeName@JsonTypeName@JsonSubTypeExampleJava ObjectsSerializing and deserializinginclude = JsonTypeInfo.As.WRAPPER_OBJECT原文链接
@JsonTypeInfo 的 use = JsonTypeInfo.Id.CLASS,会将完全限定类名序列化为类型标识符。当非 Java 客户端使用被序列化的 JSON 时,Java
使用@SerializedName注解解决json属性名和实体类名称不一致问题
首先引入依赖
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version
本文实例讲述了Laravel5.1 框架模型多态关联用法。分享给大家供大家参考,具体如下:
什么是多态关联? 一个例子你就明白了:好比如说评论 它可以属于视频类 也可以属于文章类,当有个需求是 从评论表中取到视频类的数据,这就需要用到多态关联了。
简单的一句话总结:一张表对应两张表。
1 实现多态关联
1.1 文章表的结构
public function up()
Schema::create('articles', function (Blueprint $table) {
$table->increments('id');
$table->st
C++中的多态类对象的大小取决于其成员变量和虚函数的数量和类型。一个多态类对象的大小由以下几个因素决定:
1. 成员变量:多态类对象中包含的成员变量所占用的空间大小会影响对象的总大小。每个成员变量都占用一定的字节,不同类型的成员变量可能占用不同的空间。
2. 虚函数表指针:多态类中如果有虚函数,那么每个对象都会包含一个指向虚函数表的指针(通常称为虚函数表指针),该指针占用一定的空间。
3. 虚函数表:虚函数表是一个包含虚函数指针的表格,用于实现动态绑定。虚函数表的大小取决于类中声明的虚函数数量。
因此,多态类对象的大小是以上因素之和。请注意,不同的编译器可能对内存布局和对齐方式有所不同,因此实际的对象大小可能会有所差异。