java.io.Serializable 是 Java 中的一种标记接口(marker interface)。标记接口是一种特殊的接口,java.io.Serializable 接口没有任何方法,也没有常量。

对象序列化是将对象转换为静态有序的字节流的过程,因此该对象可以用于传输或持久化。反序列化是该过程的反向操作,即将字节流转换为 Java 对象。Java 对象实现 java.io.Serializable 该接口后,就能实现序列化和反序列化。序列化在远程调用中非常常见。

暴露实体

定义 member 实体如下:

@Data  
public class Mbr implements java.io.Serializable {  
  
    private Long id;  
  
    private String name;  
  
    private String age; 
}

我们在实践中,可能会遇到不定义 dto 对象,直接在接口中暴露实体对象 create(Mbr mbr),update(Mbr mbr) 的情况,这时实体对象必须实现 java.io.Serializable 接口。

当实体实现了 java.io.Serializable 接口后,所有继承它的实体也能被序列化。如果实体里引用了其它对象,那么被引用的对象也应该可以序列化。

@Data  
public class Mbr implements java.io.Serializable {  
  
    private Long id;  
  
    private String name;  
  
    private String age; 

	// Address 应该也实现 java.io.Serializable 接口
	private Address address;
}

serialVersionUID

@Data  
public class Mbr implements java.io.Serializable {  

	private static final long serialVersionUID = 1L;
  
    private Long id;  
  
    private String name;  
  
    private String age; 
}

JVM 通过版本号(serialVersionUID) 将序列化的实体联系起来。在反序列化的过程中,JVM 会将字节流中的 serialVersionUID 与本地响应的实体类中的 serialVersionUID 比较,相同,可以序列化,否则抛出 InvaidCastException

当实体中不定义 serialVersionUID 字段时,JVM 将在运行时生成该字段。所以,这里的重点是,在开发过程中经常会变更字段,如果不定义 serialVersionUID 字段,运行时每次都会生成不同的 serialVersionUID,导致 _InvalidClassExceptions_异常。
这种问题还是挺常见的,在微服务 A 中引用另一个微服务 B 的实体(或 dto)包,B 中的实体更新,但没有更新 A 中的应用,就会引发此问题。
作者:|Zhang_Xiang|,原文链接: https://www.cnblogs.com/Zhang-Xiang/p/16297647.html

文章推荐

如何使用Map处理Dom节点

KMeans算法与GMM混合高斯聚类

Ununtu服务器安装Nginx与PHP

MySQL笔记之一致性视图与MVCC实现

TypeScript中的枚举

day11-SpringBoot中注入Servlet&Filter&Listener

Redis - 基础数据类型

apache服务资源监控

node使用multer进行文件上传

【clickhouse专栏】单机版的安装与验证

『忘了再学』Shell基础 — 20、Shell中的运算符

探究MySQL中SQL查询的成本