Java 提供了一种对象序列化的机制,该机制中,一个对象可以被表示为一个字节序列,该字节序列包括该对象的数据、有关对象的类型的信息和存储在对象中数据的类型。
将序列化对象写入文件之后,可以从文件中读取出来,并且对它进行反序列化,也就是说,对象的类型信息、对象的数据,还有对象中的数据类型可以用来在内存中新建对象。
概念
序列化:把对象转换为字节序列的过程称为对象的序列化;
反序列化:把字节序列恢复为对象的过程称为对象的反序列化。
应用场景
1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;
2) 在网络上传送对象的字节序列。
ObjectOutputStream类包含序列化一个对象的方法,下面的方法序列化一个对象,并将它发送到输出流。
public final void writeObject(Object x) throws IOException
ObjectInputStream 类包含反序列化一个对象的方法,该方法从流中取出下一个对象,并将对象反序列化。它的返回值为Object,因此,你需要将它转换成合适的数据类型。
public final Object readObject() throws IOException, ClassNotFoundException
其中一个对象要被序列化成功,需满足两个条件:
- 该类必须实现 java.io.Serializable 对象。
- 该类的所有属性必须是可序列化的。如果有一个属性不是可序列化的,则该属性必须注明是短暂(transient)的,即不参与序列化过程。
public class Student implements Serializable{
private static final long serialVersionUID = -5257722420794216987L; //序列化版本号
private int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
public class Main implements Serializable{
public static void main(String[] args) throws CloneNotSupportedException, FileNotFoundException, IOException, ClassNotFoundException{
Student s = new Student();
s.setA(10);
//序列化
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("w://a.taxt"));
//把对象写入流
o.writeObject(s);
o.close();
//反序列化
ObjectInputStream oi = new ObjectInputStream(new FileInputStream("w://a.taxt"));
//从流中读取对象
Student si = (Student)oi.readObject();
System.out.println(si.getA());
}
}
serialVersionUID有两种显示的生成方式:
一是 默认的1L,比如:private static final long serialVersionUID = 1L;
二是 根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,如:private static final long serialVersionUID = xxxxL;
serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。
serialVersionUID作用: 序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。
参考:https://www.cnblogs.com/soundcode/p/6296515.html
参考:https://www.cnblogs.com/duanxz/p/3511695.html
参考:https://blog.youkuaiyun.com/abc6368765/article/details/51365838