先来说一下什么是序列化与反序列化?
序列化:
永久的保存对象,保存对象的字节序列到本地文件中
反序列化:
将保存到本地文件中的对象读取到内存中,还原成这个对象
如何实现序列化与反序列化?
一个类如果想被序列化,则必须实现java.io.Serializable接口,这个接口没有定义任何方法,是一个标志性接口,当一个类实现了该接口,就表示这个类的对象是可以被序列化的
下面说一下序列化的时候,需要注意的问题
1.当一个对象被序列化的时候,只保存对象的非静态成员变量,因为静态成员与方法是属于类的成员
2.如果一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存
3.如果一个可序列化对象包含了某个不可序列化对象的引用,那么整个序列化是会失败的,并且会抛出一个NotSerializableException,我们可以将这个引用标记为transient,表示为短暂的,此时该变量就无法被序列化,然后对象依旧可以被序列化
下面介绍一下序列化与反序列化用到的两个对象与方法
1.序列化对象与方法
上面序列化是要把对象写出去,因此就要用到ObjectOutputStream流
这里还需要说明一点的就是,序列化一般在外部存储文件,该文件的扩展名一般就叫.ser
2.反序列化的对象与方法
下面我们来看代码实例
先来看我们需要序列化的一个类
Person
package domain; import java.io.Serializable; import java.util.Date; public class Person implements Serializable { String name; int age; String gender; //添加了一个短暂属性,表明这个字段不可别序列化 transient Date birthday; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } 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 String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } }
序列化类SerializeTest1.java
package test; import domain.Person; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.Date; public class SerializeTest1 { public static void main(String[] args) throws IOException { Person p = new Person(); p.setName("王二麻子"); p.setAge(520); p.setGender("男"); p.setBirthday(new Date()); //建立一个序列化对象 FileOutputStream fis = new FileOutputStream("D:/w.ser"); ObjectOutputStream oos = new ObjectOutputStream(fis); oos.writeObject(p); oos.close(); fis.close(); } }
这个就会在指定位置给我们产生一个文件
但是你不要打开这个看啊,因为这个肯定是乱码,毕竟是一个序列化文件,属于正常情况
然后去看我们的反序列化文件Deserialize.java
package test; import domain.Person; import java.io.*; public class DeserializeTest1 { public static void main(String[] args) { //将文件进行反序列化 Person p = null; //建立一个反序列化对象 //这里是.ser序列化的文件 FileInputStream fis = null; ObjectInputStream objectInputStream = null; try { fis = new FileInputStream("D:/w.ser"); objectInputStream = new ObjectInputStream(fis); p = (Person) objectInputStream.readObject(); } catch (Exception e) { e.printStackTrace(); }finally{ try { objectInputStream.close(); } catch (IOException e) { e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } //上面就会反序列化之前我们在文件中存放的对象 //然后访问一下之前创建的对象 System.out.println("Name: " + p.getName()); System.out.println("age: " + p.getAge()); System.out.println("gender: " + p.getGender()); System.out.println("birthday: " + p.getBirthday()); } }
运行结果:
这里在说一下为什么birthday是NULL,不是之前设置了值吗?你忘啦,我们添加了transient短暂属性,所以它不会被序列化的。
再见。