将内存中的对象序列化到硬盘
package com.javaxl.io.other; import java.io.*; /** * @author 小李飞刀 * @site www.javaxl.com * @company * @create 2019-06-16 8:51 * * 常见错误 * 没有实现Serializable接口 * java.io.NotSerializableException: com.javaxl.io.other.Person * 对象序列化前后唯一标识不匹配(这里我把person 的name的修饰符由private改成protected) * java.io.InvalidClassException: com.javaxl.io.other.Person; local class incompatible: stream classdesc serialVersionUID = 1519549123738465531, local class serialVersionUID = 2130208101218075637 */ public class ObjectStreamDemo { public static void main(String[] args) throws IOException, ClassNotFoundException { // writeObj(); readObj(); } /** * 将内存中的数据写入硬盘(对象序列化) * @throws IOException * @throws ClassNotFoundException */ public static void writeObj() throws IOException, ClassNotFoundException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\obj.txt")); oos.writeObject(new Person("zs",22)); oos.close(); } /** * 将硬盘中的数据加载进内存(对象反序列化) * @throws IOException * @throws ClassNotFoundException */ public static void readObj() throws IOException, ClassNotFoundException { ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\obj.txt")); Person p = (Person)ois.readObject(); System.out.println(p); ois.close(); } } class Person implements Serializable{ private final static long serialVersionUID = 1519549123738465531L; private String name; transient int age; static String country = "cn"; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public static String getCountry() { return country; } public static void setCountry(String country) { Person.country = country; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
图解内存中对象序列化过程
1、jvm虚拟机加载Person.class
2、当具体代码中使用了Person.class创建了对象,那么在堆内存中开辟空间存放对象实例;
这时的对象实例会随着方法执行结束而消失;
3、而序列化的操作是将,内存中的类实例持久化到硬盘,以便下次程序运行时使用;
注意:
Serializable作为一个标记接口,它是根据类的成员而计算出一个唯一标识,用来序列化的;
这也就意味着,当序列化前与序列化后类成员一定要保持一致,才能进行反序列化;否者反序列化失败,原因在于类成员发生改变,唯一标识也会发生改变;两次的唯一标识不一致,自然反序列化失败;
如果想要类成员发生改变后,依然反序列化成功,我们可以将唯一标识写死即可;
从上图中可以看出,对象序列化只跟jvm中堆内存有关;
所以当class文件中的 属性被static所修饰,那么该属性是不会被序列化的,因为static修饰的成员都在静态区/方法区;
另外,被transient修饰的属性,也不会被序列化;
备案号:湘ICP备19000029号
Copyright © 2018-2019 javaxl晓码阁 版权所有