Java序列化与反序列化

﹏ヽ暗。殇╰゛Y 2022-07-16 06:50 341阅读 0赞

1、Java序列化与反序列化(what)
Java序列化是指把Java对象转换为字节序列的过程;而Java反序列化是指把字节序列恢复为Java对象的过程。序列化是Java中实现持久化存储的一种方法。
2、为什么需要序列化与反序列化(why)
我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等,而这些数据都会以二进制序列的形式在网络上传送。那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的。如何做到呢?这就需要Java序列化与反序列化了。换句话说,一方面,发送方需要把这个Java对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出Java对象。
3、序列化主要有两种用途(where)
一是实现了数据的持久化,通过序列化可以把把对象的字节序列永久地保存到硬盘上(通常存放在文件里);
二是利用序列化实现远程通信,即在网络上传送对象的字节序列。
3.1 如何实现Java序列化与反序列化(how)
3.1.1 JDK类库中序列化API
1)java.io.ObjectOutputStream:表示对象输出流(序列化)
它的writeObject(Object obj)方法可以对参数指定的obj对象进行序列化,把得到的字节序列写到一个目标输出流中。
2)java.io.ObjectInputStream:表示对象输入流(反序列化)
它的readObject()方法源输入流中读取字节序列,再把它们反序列化成为一个对象,并将其返回。
3.1.2 实现序列化的要求
只有实现了Serializable或Externalizable接口的类的对象才能被序列化,否则抛出异常。
3.1.3 实现Java对象序列化与反序列化的方法
假定一个Student类,它的对象需要序列化,可以有如下三种方法:

1)方法一:
若Student类仅仅实现了Serializable接口,则可以按照以下方式进行序列化和反序列化。
ObjectOutputStream采用默认的序列化方式,对Student对象的非transient的实例变量进行序列化。
ObjcetInputStream采用默认的反序列化方式,对对Student对象的非transient的实例变量进行反序列化。

2)方法二:
若Student类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化。
ObjectOutputStream调用Student对象的writeObject(ObjectOutputStream out)的方法进行序列化。
ObjectInputStream会调用Student对象的readObject(ObjectInputStream in)的方法进行反序列化。

3)方法三:
若Student类实现了Externalnalizable接口,且Student类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。
ObjectOutputStream调用Student对象的writeExternal(ObjectOutput out))的方法进行序列化。
ObjectInputStream会调用Student对象的readExternal(ObjectInput in)的方法进行反序列化。

4)JDK类库中序列化的步骤
步骤一:
创建一个对象输出流,它可以包装一个其它类型的目标输出流,如文件输出流:
ObjectOutputStream out = new ObjectOutputStream(new fileOutputStream(“D:\objectfile.obj”));
步骤二:
通过对象输出流的writeObject()方法写对象:
out.writeObject(“Hello”);
out.writeObject(new Date());

5)JDK类库中反序列化的步骤
步骤一:
创建一个对象输入流,它可以包装一个其它类型输入流,如文件输入流:
ObjectInputStream in = new ObjectInputStream(new fileInputStream(“D:\objectfile.obj”));
步骤二:
通过对象输出流的readObject()方法读取对象:
String obj1 = (String)in.readObject();
Date obj2 = (Date)in.readObject();
说明:为了正确读取数据,完成反序列化,必须保证向对象输出流写对象的顺序与从对象输入流中读对象的顺序一致。
Student类定义如下:

  1. import java.io.Serializable;
  2. /** *Title:学生类 *Description:实现序列化接口的学生类 *Copyright: copyright(c) 2012 *Filename: Student.java */
  3. public class Student implements Serializable {
  4. private String name;
  5. private char sex;
  6. private int year;
  7. private double gpa;
  8. public Student() {
  9. }
  10. public Student(String name,char sex,int year,double gpa)
  11. {
  12. this.name = name;
  13. this.sex = sex;
  14. this.year = year;
  15. this.gpa = gpa;
  16. }
  17. public void setName(String name)
  18. {
  19. this.name = name;
  20. }
  21. public void setSex(char sex)
  22. {
  23. this.sex = sex;
  24. }
  25. public void setYear(int year)
  26. {
  27. this.year = year;
  28. }
  29. public void setGpa(double gpa)
  30. {
  31. this.gpa = gpa;
  32. }
  33. public String getName()
  34. {
  35. return this.name;
  36. }
  37. public char getSex()
  38. {
  39. return this.sex;
  40. }
  41. public int getYear()
  42. {
  43. return this.year;
  44. }
  45. public double getGpa()
  46. {
  47. return this.gpa;
  48. }
  49. }

把Student类的对象序列化到文件O:\Java\com\jieke\io\student.txt,并从该文件中反序列化,向console显示结果。代码如下:

  1. /** *Title:应用学生类 *Description:实现学生类实例的序列化与反序列化 *Filename: UseStudent.java */
  2. public class UseStudent {
  3. public static void main(String[] args)
  4. {
  5. Student st = new Student("Tom",'M',20,3.6);
  6. File file = new File("O:\\Java\\com\\jieke\\io\\student.txt");
  7. try{
  8. file.createNewFile();
  9. }catch(IOException e){
  10. e.printStackTrace();
  11. }
  12. try{
  13. //Student对象序列化过程
  14. FileOutputStream fos = new FileOutputStream(file);
  15. ObjectOutputStream oos = new ObjectOutputStream(fos);
  16. oos.writeObject(st);
  17. oos.flush();
  18. oos.close();
  19. fos.close();
  20. //Student对象反序列化过程
  21. FileInputStream fis = new FileInputStream(file);
  22. ObjectInputStream ois = new ObjectInputStream(fis);
  23. Student st1 = (Student) ois.readObject();
  24. System.out.println("name = " + st1.getName());
  25. System.out.println("sex = " + st1.getSex());
  26. System.out.println("year = " + st1.getYear());
  27. System.out.println("gpa = " + st1.getGpa());
  28. ois.close();
  29. fis.close();
  30. }catch(ClassNotFoundException e){
  31. e.printStackTrace();
  32. }catch (IOException e){
  33. e.printStackTrace();
  34. }
  35. }
  36. }

结果如下所示:
name = Tom
sex = M
year = 20
gpa = 3.6

4、总结
4.1 Java序列化就是把对象转换成字节序列,而Java反序列化就是把字节序列还原成Java对象。
4.2 采用Java序列化与反序列化技术,一是可以实现数据的持久化,在MVC模式中很是有用;二是可以对象数据的远程通信。

发表评论

表情:
评论列表 (有 0 条评论,341人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java序列序列

    序列化:java对象转化为字节序列,反序列化:字节序列转化为java对象 好处:其好处一是实现了数据的持久化,通过序列化可以把数据永久地保存到硬盘上(通常存放在文件里),

    相关 Java序列序列

    Java序列化与反序列化是什么?为什么需要序列化与反序列化?如何实现Java序列化与反序列化?本文围绕这些问题进行了探讨。  1.Java序列化与反序列化  Java序列化

    相关 Java序列序列

    基本概念: 序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。 昨天在一

    相关 java 序列序列

    一、什么是序列化与反序列化? > Java 序列化是指把 Java 对象转换为字节序列的过程; > Java 反序列化是指把字节序列恢复为 Java 对象的过程; 二、