项目中的实体类继承与序列化

关于项目中的实体类书写相关知识点。

实体类属性继承-返回前端

实体类

1
2
3
4
5
6
@Getter
@Setter
public class FatherEntity {
String home;
String city;
}
1
2
3
4
5
6
@Setter
@Getter
public class SonEntity extends FatherEntity{
String name;
String sex;
}

Controller(不设置属性)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@RestController
@RequestMapping("/test")
public class TestController {

/**
* 测试子类继承父类后会不会返回父类的属性
* @author wahoyu
* @time 2023/8/24
*/
@GetMapping("/getSonProperty")
public Result getSonProperty(){
SonEntity son = new SonEntity();
//son.setHome("千金");
//son.setSex("男");
//son.setName("王熊二");
//son.setCity("本溪");
return ResultResponse.success(son);
}
}

测试结果

Controller(设置属性)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@RestController
@RequestMapping("/test")
public class TestController {
/**
* 测试子类继承父类后会不会返回父类的属性
* @author wahoyu
* @time 2023/8/24
*/
@GetMapping("/getSonProperty")
public Result getSonProperty(){
SonEntity son = new SonEntity();
son.setHome("千金");
son.setSex("男");
son.setName("王熊二");
son.setCity("本溪");
return ResultResponse.success(son);
}
}

测试结果

实体类属性继承-sout

Serializable接口与serialVersionID

参考文章:

代码实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Getter
@Setter
@TableName("student")
public class Student implements Serializable {

private static final long serialVersionUID=1L;

@TableId(value = "id", type = IdType.AUTO)
private Integer id;

private String name;
private Integer age;

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
@TableField(fill = FieldFill.INSERT)
private LocalDateTime createTime;

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss" , timezone = "GMT+8")
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;


}

我们发现mybatisplus生成的实体类和我们平时创建的实体类有两个不同:

  1. 引用了Serializable这个接口
  2. 定义了一个serialVersionUID变量。

他们是做什么的?

Seriazable接口

一个对象序列化的接口,一个类只有实现了Serializable接口,它的对象才能被序列化。

什么是序列化?

序列化:是将对象状态转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时存储区或持久性存储区,之后,便可以通过从存储区中读取或反序列化对象的状态信息,来重新创建该对象。同时与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

为什么要序列化对象?

当我们需要把对象的状态信息通过网络进行传输,或者需要将对象的状态信息持久化,以便将来使用时都需要把对象进行序列化。

当我们需要把对象的状态信息通过网络进行传输,或者需要将对象的状态信息持久化,以便将来使用时都需要把对象进行序列化

那为什么还要继承Serializable?那是因为存储对象在存储介质中,以便在下次使用的时候,可以很快捷的重建一个副本。

序列化与反序列化?

把对象转换为字节序列的过程称为对象的序列化.把字节序列恢复为对象的过程称为对象的反序列化。

探究Serializable接口的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package java.io;

/**
*......................
*.....................
* @author unascribed
* @see java.io.ObjectOutputStream
* @see java.io.ObjectInputStream
* @see java.io.ObjectOutput
* @see java.io.ObjectInput
* @see java.io.Externalizable
* @since JDK1.1
*/
public interface Serializable {
}

可以看到,Serializable接口里面什么都没有。这说明此接口是一个声明式接口,或者说是标识接口。

标识接口存在的意义是什么?

例如:在课堂上有位学生遇到一个问题,想举手提问,那么这位学生的举手其实就是一个标识,自己解决不了问题请教老师帮忙解决。

在Java中的这个Serializable接口其实是给jvm看的,通知jvm,我不对这个类做序列化了,你(jvm)帮我序列化就好了。

关于JavaBean是否需要实现Serializable接口

为什么mybatisplus生成的实体类要实现Serializable接口?

主要的原因是因为存储的内容可能会超出,然后就会存储到内存中,要用的时候要序列化,所以这里继承是为了有备无患;

MyBatis-Plus是一个增强版的MyBatis框架,它对MyBatis进行了扩展和增强。在MyBatis-Plus的代码生成器中,生成的实体类默认会实现Serializable接口。

通过实现 Serializable 接口,实体类的对象可以进行序列化和反序列化的操作。这在以下场景中非常有用:

  • 缓存:可以将实体对象序列化后存储在缓存中,以提高系统性能和响应速度。
  • 分布式环境:在分布式系统中,可以将实体对象进行序列化后在网络中传输,用于远程调用或分布式缓存。
  • 持久化存储:将实体对象序列化后,可以直接将其写入到文件系统或数据库中,以便长期存储。

为什么我们自己创建的实体类不实现实现Serializable接口也可以正常使用?

自己创建的实体类不需要实现 Serializable 接口也可以正常使用,这是因为 Serializable 接口在Java中是一个可选的接口。当我们不需要将实体对象进行序列化操作时,可以不必实现 Serializable 接口。这在大多数情况下是可以接受的,并且可以减少一些额外的代码和复杂性。

但需要注意的是,如果你的实体类对象需要在不同的系统或场景中进行序列化、传输或持久化存储,那么建议实现 Serializable 接口,以确保对象的可序列化性。

总结

MyBatis-Plus 生成的实体类实现 Serializable 接口是为了使实体对象具备序列化的能力,方便在分布式环境下的远程调用、缓存和持久化存储等操作。而自己创建的实体类不一定需要实现 Serializable 接口,可以根据具体需求决定是否实现。

为什么要定义serialversionUID变量?

如果可序列化类没有显式声明serialVersionUID,然后,序列化运行时将根据类的各个方面计算该类的默认serialVersionUID值,如Java(TM)对象序列化规范中所述。

从说明中我们可以看到,如果我们没有自己声明一个serialVersionUID变量,接口会默认生成一个serialVersionUID

但是强烈建议用户自定义一个serialVersionUID,因为默认的serialVersinUID对于class的细节非常敏感,反序列化时可能会导致InvalidClassException这个异常。

为什么要指定serialVersionUID?

刚开始提到了,serialVersionUID要不要指定呢?如果不指定会出现什么样的后果?如果指定了以后后边的值又代表着什么意思呢?既然系统指定了这个字段,那么肯定是有它的作用的。

这个serialVersionUID是用来辅助对象的序列化与反序列化的,原则上序列化后的数据当中的serialVersionUID与当前类当中的serialVersionUID一致,那么该对象才能被反序列化成功。这个serialVersionUID的详细的工作机制是:在序列化的时候系统将serialVersionUID写入到序列化的文件中去,当反序列化的时候系统会先去检测文件中的serialVersionUID是否跟当前的文件的serialVersionUID是否一致,如果一直则反序列化成功,否则就说明当前类跟序列化后的类发生了变化,比如是成员变量的数量或者是类型发生了变化,那么在反序列化时就会发生crash,并且回报出错误


项目中的实体类继承与序列化
http://wahoyu.xyz/2023/08/25/EntitySerializable/
作者
Wahoyu
发布于
2023年8月25日
许可协议