黑马程序员技术交流社区

标题: Java对象序列化学习 [打印本页]

作者: 别想太多    时间: 2015-5-25 14:13
标题: Java对象序列化学习
1.序列化定义
序列化分为两大部分:序列化(serialization)和反序列化(deserialization)。序列化是将数据分解成字节流,以便存储在文件 中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象 实例。ObjectOutputStream中的序列化过程与字节流连接,包括对象类型和版本信息。反序列化时,JVM用头信息生成对象实例,然后将对象 字节流中的数据复制到对象数据成员中。

2.主要涉及的类
ObjectOutputStream类扩展DataOutput接口。writeObject()方法是最重要的方法,用于对象序列化。如果对象包含其 他对象的引用,则writeObject()方法递归序列化这些对象。每个ObjectOutputStream维护序列化的对象引用表,防止发送同一对 象的多个拷贝。由于writeObject()可以序列化整组交叉引用的对象,因此同一ObjectOutputStream实例可能不小心被请求序列化 同一对象。
这时,进行反引用序列化,而不是再次写入对象字节流。例如:
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("Login.out"));
o.writeObject(new Date());
o.close();

ObjectInputStream类扩展DataInput接口。ObjectInputStream中的方法镜像DataInputStream中读 取Java基本数据类型的公开方法。readObject()方法从字节流中反序列化对象。每次调用readObject()方法都返回流中下一个 Object。对象字节流并不传输类的字节码,而是包括类名及其签名。readObject()收到对象时,JVM装入头中指定的类。如果找不到这个类, 则readObject()抛出ClassNotFoundException。
ObjectInputStream in = new ObjectInputStream(new FileInputStream("Login.out"));
Date d = (Date) in.readObject();

3.定制序列化过程
序列化通常可以自动完成,但有时可能要对这个过程进行控制。java可以将类声明为serializable,但仍可手工控制声明为static或 transient的数据成员。 序列化时,类的所有数据成员应可序列化除了声明为transient或static的成员。将数据成员声明为transient后,java可以逐个关闭 序列化,用Bruce Eckel的话说“不用麻烦你保存或者恢复数据-------我自己会处理的!”
例如:
某个Login对象保存某个特定的登录会话信息,登录的合法性通过校验以后,我们想把数据保存下来,但是不保存密码。可以采用定制序列化方
法解决问题。
  1. import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.ObjectInputStream;
  4. import java.io.ObjectOutputStream;
  5. import java.io.Serializable;
  6. import java.util.Date;

  7. public class Login implements Serializable {
  8.        private Date date = new Date();
  9.        private String username;
  10.        private transient String password;
  11.        public Login(String name, String pwd) {
  12.               username = name;
  13.               password = pwd;
  14.        }
  15.         public String toString() {
  16.               String pwd = (password == null) ? "(n/a)" : password;
  17.               return "Login info:\n username:" + username
  18.               + "\n date:" + date
  19.               + "\n password:" + pwd;
  20.        }


  21. public static void main(String[] args) throws Exception{
  22.   Login a=new Login("bread","bread");
  23.   System.out.println("Login a="+a);
  24.   ObjectOutputStream o=new ObjectOutputStream(new FileOutputStream("Login.out"));
  25.   o.writeObject(a);
  26.   o.close();
  27.   Thread.sleep(1000);
  28.   ObjectInputStream in=new ObjectInputStream(new FileInputStream("Login.out"));
  29.   System.out.println("Recovering object at"+new Date());
  30.   a=(Login)in.readObject();
  31.   System.out.println("Login a="+a);
  32. }
  33. }
复制代码

执行结果如下:
Login a=Login info:
username:bread
date:Thu Oct 26 18:44:41 CST 2006
password:bread
Recovering object atThu Oct 26 18:44:44 CST 2006
Login a=Login info:
username:bread
date:Thu Oct 26 18:44:41 CST 2006
password:(n/a)

作者: 半世心修    时间: 2015-5-25 14:22
看上去不错 ,先顶再看
作者: 杨宇俊    时间: 2015-5-25 22:21
顶一个!
作者: 追忆似水年华    时间: 2015-5-25 22:36
顶一个+1.




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2