一、入门
首先当然得理解什么是序列化和反序列化
- 序列化是将Java对象序列化成二进制(即字节序列)的过程。
- 反序列是将被字节序列重新变成Java对象的过程。
理解:本质上是改变了Java对象的生存周期,使得Java对象可以持久化存储,同时也实现了对象也可以作为网络传输的数据。
二、如何实现
通过继承 Serializable 接口便可实现对象的序列化。
挖坑:查看Serializable 接口可以看到是空实现,具体作用下面讲解
怎么实现直接上代码(ps:例子是抄的附上链接 序列化和反序列化的底层实现原理是什么)
public class SerialDemo {
public static void main(String[] args) throws IOException, ClassNotFoundException {
//序列化
FileOutputStream fos = new FileOutputStream("object.out");
ObjectOutputStream oos = new ObjectOutputStream(fos);
User user1 = new User("xuliugen", "123456", "male");
oos.writeObject(user1);
oos.flush();
oos.close();
//反序列化
FileInputStream fis = new FileInputStream("object.out");
ObjectInputStream ois = new ObjectInputStream(fis);
User user2 = (User) ois.readObject();
System.out.println(user2.getUserName()+ " " +
user2.getPassword() + " " + user2.getSex());
//反序列化的输出结果为:xuliugen 123456 male
}
}
public class User implements Serializable {
public static final long serialVersionUID = 42L;
private String userName;
private String password;
private String sex;
//全参构造方法、get和set方法省略
}
注意
- static和transient修饰的属性不能被序列化
理解:
static修饰的属性值是存储在当前JVM中的
transient是因为这个关键字的特性就是防止一些属性被序列化,因为有一些敏感信息不想被别人访问(比如密码,你要是持久化对象了,别人就能读到你的密码了!)
- 还有一个需要注意的点是那个大家都说的serialVersionUID
理解:
序列化时使用一个称为 serialVersionUID 的版本号与每个可序列化类相关联,该序列号用在反序列化过程中,验证这个字节序列是否能够被转化的对象所兼容。(简单来说,就是如果反序列时定义的类的serialVersionUID和序列化时的类定义的serialVersionUID不一样,就不能被反序列。)
为它赋予明确的值。显式地定义serialVersionUID有两种用途:
1.在某些场合,希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有相同的serialVersionUID;
2.在某些场合,不希望类的不同版本对序列化兼容,因此需要确保类的不同版本具有不同的serialVersionUID。
三、理解
如前所述,序列化和反序列化本质上是改变了Java对象的生存周期,使得Java对象可以持久化存储,同时也实现了对象也可以作为网络传输的数据。
所以,在理解序列化和反序列化的时候,不应该将它作为Java语言仅有的特性去理解,这其实就是一种解决对象存储问题的实现机制。