1、定义
什么是序列化:就是将一个对象转化字节流的过程,可以将其保存到硬盘上,也可以通过网络传输到其他程序,主要用于持久化,远程通信,跨进程请求访问。
什么是反序列化:反序列化就是和序列化相反的过程。,将字节流转化为对象,这也是一种创建对象的方法。并且序列化和反序列化是平台无关性的,进行序列化的对象在不同的平台能够进行反序列化。
2、如何实现序列化
通过实现Serializable接口,Serializable接口实际是个空接口,不含任何属性,方法,实现该接口表示该类可以实现序列化,如果该类没有实现该接口而进行序列化,我们将得到一个 RuntimeException 异常:主线程中出现异常 java.io.NotSerializableException。
public class x3 implements Serializable {
private int a;
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
}
public class MainMethod {
public static void main(String[] args) {
xvliehua(); //将对象序列化,保存到G盘a.txt文件
fxvliehua(); //反序列化
}
private static void fxvliehua() {
try {
FileInputStream fi = new FileInputStream("G:\\a.txt");
ObjectInputStream ob = new ObjectInputStream(fi);
x3 x3=(x3)ob.readObject();
System.out.println(x3.getA());
} catch (Exception e) {
e.printStackTrace();
}
}
private static void xvliehua() {
x3 x3 = new x3();
x3.setA(1);
try {
FileOutputStream fos = new FileOutputStream("G:\\a.txt");
ObjectOutputStream ob = new ObjectOutputStream(fos);
ob.writeObject(x3);
ob.close();
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
注意事项!!!
1、如果一个类实现序列化,其子类也自动实现序列化,不需要显示实现Serializable接口
2、如果一个类的子类实现序列化,其父类没有实现序列化,则只有子类对象序列化,且父类中必须提供无参的构造函数,否则抛出java.io.InvalidClassException,因为父类没有序列化,进行反序列化创建对象,需要先构造父类,再构造子类,反序列化没有父类对象,便调用父类无参构造方法。
3、如果一个实现序列化的类引用其他,那该对象也将序列化
4、类中的方法无法序列化,只有属性序列化
3、serialVersionUID
serialVersionUID是一个标识符,通常使用对象哈希吗序列化标记对象上,主要用来控制版本。
如果不添加,如果版本的改变可能无法进行反序列化,例如:对该类进行某些属性的增加或删除,系统会重新计算该类的hash值并复制给serialVersionUID,当进行反序列化时,被序列化的二进制文件中的serialVersionUID和当前类的serialVersionUID不一致,便会转换失败,
如果手动指定,如指定为1L,可以根据当前类结构自动生成hash值,保证serialVersionUID能够相同,反序列化能够成功,但是如果类发生非城规改变,如类名改变,一样还是会反序列化失败。因为虽然serialVersionUID通过,但是无法从老版本还原一个新类结构对象。
4、Transient 关键字
如果对象序列化时,我们想要某些属性不被序列化,则可以Transient 关键字修饰,jvm将会以默认值读取到文件中,
static,static本身是优先于对象存在的,所以被static修饰本身就不会序列化,不用加Transient 关键字,
final :final关键字修饰一定序列化,不管有没有被Transient 关键字修饰