一、概念
为什么会有序列化?平时我们所说的java内存中的对象是无法进行网络通信和IO操作的,对象将以序列化的存储状态(表现形式)被它们所识别。
- 序列化:将一个对象转换成一串二进制表示的字节数组,通过保存或转移这些字节数组达到持久化的目的。
- 反序列化:将字节数组重组成对象。
二、实现
序列化只需要实现java.io.Serializable接口就可以了。序列化的时候有一个serialVersionUID参数,Java序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的。在进行反序列化,Java虚拟机会把传过来的字节流中的serialVersionUID和本地相应实体类的serialVersionUID进行比较,如果相同就认为是一致的实体类,可以进行反序列化,否则Java虚拟机会拒绝对这个实体类进行反序列化并抛出异常。
serialVersionUID有两种生成方式:
- 默认的1L。
- 根据类名、接口名、成员方法以及属性等来生成一个64位的Hash字段。
Java为用户定义了默认的序列化、反序列化方法,其实就是ObjectOutputStream的defaultWriteObject方法和ObjectInputStream的defaultReadObject方法。
实例:
import lombok.Data;
import java.io.*;
/**
* 序列化
*
* @author wangmaoyu
* @create 2018-06-06 11:33
**/
@Data
public class SerializableObject implements Serializable {
private String str1;
private transient String str2;
private static String str3="abc";
public SerializableObject(String str1, String str2) {
this.str1 = str1;
this.str2 = str2;
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
File file = new File("f:" + File.separator + "s.txt");
OutputStream outputStream = new FileOutputStream(file);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
objectOutputStream.writeObject(new SerializableObject("str1","str2"));
objectOutputStream.close();
FileInputStream fileInputStream = new FileInputStream(file);
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
SerializableObject serializableObject= (SerializableObject) objectInputStream.readObject();
System.out.println(serializableObject.getStr1());
System.out.println(serializableObject.getStr2());
objectInputStream.close();
}
}
结果,变量str2为null,说明以下3点:
- 序列化之后保存的是对象的信息。
- 被声明为transient的属性不会被序列化,这就是transient关键字的作用。
- 被声明为static的属性不会被序列化,这个问题可以这么理解,序列化保存的是对象的状态,但是static修饰的变量是属于类的而不是属于对象的,因此序列化的时候不会序列化它。
三、总结
- 当父类继承Serializable接口时,所有子类都可以被序列化
- 子类实现了Serializable接口,父类没有,父类中的属性不能序列化(不报错,数据丢失),但是在子类中属性仍能正确序列化。
- 如果序列化的属性是对象,则这个对象也必须实现Serializable接口,否则会报错。
- 反序列化时,如果对象的属性有修改或删减,则修改的部分属性会丢失,但不会报错。
- 反序列化时,如果serialVersionUID被修改,则反序列化时会失败。