最近公司的在做服务化,需要把所有model包里的类都实现 Serializable 接口,同时还要显示指定serialVersionUID 的值。听到这个需求,我脑海里就突然出现了好几个问题,比如说:
(1) 序列化和反序列化是什么?
(2) 实现序列化和反序列化为什么要实现 Serializable 接口?
(3) 实现 Serializable 接口就算了,为什么还要显示指定 serialVersionUID 的值?
(4) 我要为 serialVersionUID 指定个什么值?
下面我们来一一解答这几个问题。
一、序列化和反序列化
- 序列化:把对象转换为字节序列的过程称为对象的序列化。
- 反序列化:把字节序列恢复为对象的过程称为对象的反序列化。
二、什么时候需要序列化
当我们只在本地JVM里运行下Java实例,这个时候是不需要什么序列化和反序列化的,但当我们需要将内存中的对象持久化到磁盘、数据库中时,当我们需要与浏览器进行交互时,当我们需要实现RPC时,这个时候就需要序列化和反序列化了。
前两个需要用到序列化和反序列化的场景,是不是让我们有一个很大的疑问?我们在与浏览器交互时,还有将内存中的对象持久化到数据库中时,好像都没有去进行序列化和反序列化,因为我们都没有实现 Serializable 接口,但一直正常运行。
下面先给出结论:
只要我们对内存中的对象进行持久化或网络传输,,这个时候都需要序列化和反序列化。
理由:
服务器与浏览器交互时真的没有用到 Serializable 接口吗?JSON 格式实际上就是将一个对象转化为字符串, 所以服务器与浏览器交互时的数据格式其实是字符串, 我们来看来 String 类型的源码:
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
/** Cache the hash code for the string */
private int hash; // Default to 0
/** use serialVersionUID from JDK 1.0.2 for interoperability */
private static final long serialVersionUID = - 6849794470754667710L;
......
}
String 类型实现了 Serializable 接口,并显示指定 serialVersionUID 的值.
然后我们再来看对象持久化到数据库中时的情况,Mybatis数据库映射文件里的insert代码:
<insert id="insertUser" parameterType="org.tyshawn.bean.User">INSERT INTO t_user(name, age) VALUES (#{name}, #{age})
</insert>
实际上我们并不是将整个对象持久化到数