简单介绍下序列化
序列化
将java中的对象以文件的形式保存到硬盘服务器中的过程称之为序列化
序列化主要作用
1、将对象保存成文件,方便之后反序列化获取文件中的对象
2、网络编程中远程传输对象
ObjectOutputStream 序列化类
ObjectInputStream 反序列化类
序列化注意事项:
所有序列化对象必须是实现了java.io.Serializable接口
定义:
Java序列化就是指把Java对象转换为字节序列的过程(生成了一个打开是乱码的二进制文件)
Java反序列化就是指把字节序列恢复为Java对象的过程。
serialVersionUID
一个对象数据,在反序列化过程中,如果序列化串中的serialVersionUID与当前对象值不同,则反序列化失败,否则成功。
如果serialVersionUID没有显式生成(使用系统默认生成的),系统就会自动生成一个。生成的输入有:类名、类及其属性修饰符、属性、构造器...。任何一项的改变都会导致serialVersionUID变化,也就是说只要你的class类中有一丢丢变化你都无法反序列化出来。
属性的变化都会导致自动生成的serialVersionUID发生变化。例如,对于对象A,我们生成序列化的S(A),然后修改A的属性,则此时A的serialVersionUID发生变化。反序列化时,S(A)与A的serialVersionUID不同,无法反序列化。会报序列号版本不一致的错误。为了避免这种问题, 一般都会要求实现serialiable接口的类显式的声明一个serialVersionUID。
例子
对于一个类
public class Dog extends Animal{
private int tooth;
public Dog() {
}
public Dog(String name, int weight, int tooth) {
super(name, weight);
this.tooth = tooth;
}
}
一个抽象类
public abstract class Animal implements Serializable {
private String name;
private int weight;
public Animal() {
}
public Animal(String name, int weight) {
this.name = name;
this.weight = weight;
}
}
Dog继承了Animal抽象类,Animal实现了序列化接口,那么Dog也相当于实现了序列化接口
测试:
目前有两个方法
serializable()序列化,
unserializable()反序列化
public static String serializable(Object o){ try { File file = new File("e:/pet.obj"); if(!file.exists()){ file.createNewFile(); } ObjectOutputStream out = new ObjectOutputStream( new FileOutputStream(file)); out.writeObject(o); out.close(); return "成功"; } catch (Exception e) { e.printStackTrace(); return "失败"; } } public static Object unserializable(){ try { File file = new File("e:/pet.obj"); if(!file.exists()){ serializable(new ArrayList<Animal>()); } ObjectInputStream in = new ObjectInputStream( new FileInputStream(file)); return in.readObject(); } catch (Exception e) { e.printStackTrace(); return null; } }
我们在main方法中调用序列化一个类
public static void main(String[] args) { String 陈dog = SerializableUtil.serializable(new Dog("陈dog", 300, 3));
System.out.println(陈dog);
}
查看控制台
然后反序列化并输出控制台
public static void main(String[] args) { Animal unserializable = (Animal) unserializable();
System.out.println(unserializable);
}
控制台反序列化成功
此时我们用的是隐式serialVersionUID,也就是自己没声明
然后我们去修改下类在试试反序列化
我们给Animal类加一个属性
private int a;
再次反序列化
我们可以看到serialVersionUID不正确,也就是上面说的类中修改之后这个值就会变化,无法反序列化,下面我们显式声明一个;
get序列化类Animal新加一个serialVersionUID
private static final long serialVersionUID = 1L;
然后重复如上操作,会发现修改Animal属性之后我们也能反序列化的到对象~~
完结 干饭去咯