(一)关于序列化
(1)什么是序列化
将一个java 对象变成字节流的形式传出去或者从一个字节流中恢复成一个java 对象。例如,要将java 对象存储到硬盘或者传送给网络上的其他计算机,这个过程我们可以自己写代码去把一个java 对象变成某个格式的字节流再传输,但是,jre 本身就提供了这种支持,我们可以调用OutputStream的writeObject方法来做,如果要让java帮我们做,要被传输的对象必须实现serializable或Externalizable接口,这样,javac 编译时就会进行特殊处理,编译的类才可以被writeObject方法操作,这就是所谓的序列化。
(2)序列化的作用
在传递,和保存对象(object)的时候,保证对象的完整性和可传递性。譬如通过网络传输,或者把一个对象保存成一个文件的时候,要实现序列化接口。例如
①在web 开发中,如果对象被保存在了Session 中,tomcat 在重启时要把Session对象序列化到硬盘,这个对象就必须实现serializable或Externalizable接口。
②如果对象要经过分布式系统进行网络传输或通过rmi 等远程调用,这就需要在网络上传输对象,被传输的对象就必须实现serializable或Externalizable接口。
(3)序列化的使用
需要被序列化的类可实现两个接口之一:①实现Serializable接口;②实现Externalizable接口。
(二)方法一:实现Serializable接口的
(1)非自定义
①定义一个Person类:无需通过构造器初始化对象
public class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; public Person(String name, int age) {this.name = name; this.age = age; } //省略Get、Set..... @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } }
②Java的IO方法
/** * 序列化JAVA对象 */ @Test public void writeObjectTest(){ try { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/RUNNING_COPY.txt")); oos.writeObject(new Person("Winson", 26)); oos.writeObject(new Person("Tom", 35)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * 反序列化读取JAVA对象 */ @Test public void readObjectTest(){ ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/RUNNING_COPY.txt")); //按顺序读取 System.out.println((Person) ois.readObject()); System.out.println((Person) ois.readObject()); }
(2)自定义序列化
Person提供readObject和writeObject方法,方法内保存Person对象,序列化和反序列化的方法要一致
private void writeObject(java.io.ObjectOutputStream out){ out.writeObject(new StringBuffer(name).reverse()); out.writeInt(age); } private void readObject(java.io.ObjectInputStream in){this.name=(((StringBuffer)in.readObject()).reverse()).toString(); this.age=in.readInt(); }
(三)方法二:实现Externalizable接口,重写两个接口(和上面的自定义序列化类似),必须提供无参构造器
public class Student implements Externalizable { private static final long serialVersionUID = 1L; private String name; private int age; // 必须提供无参构造器 public Student() {} public Student(String name, int age) {this.name = name; this.age = age; } //省略Get、Set方法 @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {this.name = (((StringBuffer) in.readObject()).reverse()).toString(); this.age = in.readInt(); } @Override public void writeExternal(ObjectOutput out) throws IOException { out.writeObject(new StringBuffer(name).reverse()); out.writeInt(age); } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } }
(四)总结
(1)Serizlizable
①无需提供构造器
②可实现自定义序列化,提供writeObject、readObject方法
(2)Externalizable
①必须提供无参构造器
②必须重写writeExternal、readExternal
(3)OutputSteam和InputSteam
①创建流
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:/RUNNING_COPY.txt")); //输入
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:/RUNNING_COPY.txt")); //输出
②输入可序列化对象,writeObject()
oos.writeObject(new Person("Winson", 26)); oos.writeObject(new Person("Tom", 35)); oos.writeObject(new Student("Hello", 78)); oos.writeObject(new Student("Mary", 80));
③输出可序列化对象:必须按写入顺序读取readObject()
System.out.println((Person) ois.readObject()); System.out.println((Person) ois.readObject()); System.out.println((Student) ois.readObject()); System.out.println((Student) ois.readObject());
时间: 2024-11-10 11:34:45