java序列化详解
一.java序列化与反序列化
序列化是指把java对象(属性)转换为字节序列的过程
反序列化是指把字节序列恢复为java对象的过程
二.为什么需要序列化和反序列化
首先网络通信都是二进制的形式在传输,本地存储也是这样,那么如果我们需要在网络远程传输java对象,或者想将java对象状态持久化到磁盘,那么我们就需要这个对象可以序列化(转换为字节序列)
知道了序列化那反序列化应该也就知道了,就是将网络间传输的、磁盘上保存的对象的字节序列恢复为java对象
三.java如何实现序列化
1.jdk中的API
java.io.ObjectOutputStream:对象输出流
它的writeObject(Object obj)方法可以对obj对象进行序列化,把得到的字节序列写到一个目标输出流中
java.io.ObjectInputStream:对象输入流
它的readObject()方法从输入流中读取字节序列,再反序列化为一个对象,并将其返回;此方法返回的对象顺序和writeObject方法添加进去的对象顺序相同
2.序列化要求
需要实现Serializable或者Externalizable接口,否则抛出异常
Externalizable继承自Serializable,并添加了俩方法:
writeExternal(ObjectOutput out) readExternal(ObjectInput in)
3.实现java对象序列化和反序列化
假设一个User类,它的对象需要序列化
方法一:若User类仅仅实现了Serializable接口,则可以按照以下方法进行序列化和反序列化
ObjectOutputStream采用默认的序列化方式(writeObject方法),对User对象的所有非transient的实例变量进行序列化
ObjectInputStream采用默认的反序列化方式(readObject方法),对User对象的所有非transient的实例变量进行反序列化
方法二:若User类仅仅实现了Serializable接口,并且还定义了private void readObject(ObjectInputStream in)和private void writeObject(ObjectOutputStream out),则采用以下方式进行序列化和反序列化
ObjectOutputStream的writeObject方法会调用User对象的writeObject(ObjectOutputStream out)的方法进行序列化。
ObjectInputStream的readObject方法会调用User对象的readObject(ObjectInputStream in)的方法进行反序列化。
备注:User类中的writeObject方法和readObject方法是private的,ObjectOutputStream类在调用自身的writeObject方法的时候会检测User类中是否存在writeObject方法,如果存在就通过反射机制调用User自己的writeObject
方法三:若User类实现了Externalnalizable接口,且User类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化
ObjectOutputStream调用User对象的writeExternal(ObjectOutput out))的方法进行序列化
ObjectInputStream调用User对象的readExternal(ObjectInput in)的方法进行反序列化
备注:实现此接口的类在进行序列化和反序列化的时候所有想保存状态的属性都要手动在writeExternal和readExternal方法中write和read
四.实例
//User.java public class User implements Serializable{ private static final long serialVersionUID = 1L; String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "User [name=" + name + "]"; } }
测试
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\u.src")); User u = new User(); u.setName("name1"); oos.writeObject(u); User uu = new User(); uu.setName("name2"); oos.writeObject(uu); oos.flush(); oos.close(); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\u.src")); User o = (User)ois.readObject(); User oo = (User)ois.readObject(); System.out.println(o); System.out.println(oo); }
结果:
User [name=name1]
User [name=name2]
五.