[关闭]
@XQF 2017-02-14T13:53:19.000000Z 字数 4389 阅读 985

对象序列化

java


序列化在java编程思想上还是没有怎么见过,只是在HeadFirstJava上看过一些,不过也是忘得差不多了。现在就来好好的回顾一下。

对象的寿命通常随着生成该对象的程序的终止而终止。但是有时候我们需要将对象的状态保存下来,在需要的时候将对象恢复。我们把对象的这种能记录自己状态以便将来再生的能力叫做对象的持久性。对象通过写出描述自己状态的数值来记录自己,这个过程叫做对象的序列化。

如果一个对象可以被存放在磁盘上,或者可以发送到另外一台机器并存放到存储器或磁盘上,那么这个对象就被称为可序列化的。Java对象序列化不仅保留一个对象的数据,而且**递归保存对象引用的每个对象的数据

java序列化比较简单,通常不需要编写保存和恢复对象状态的定制代码。实现Java.serializable接口的类对象可以转换册成字节流或从字节流恢复,不需要在类中增加任何代码。不过,这个接口不需要我们在里面实现任何方法,实现接口的意义就是贴一个标签。代表该对象是可序列化的。

序列化:

要序列化一个对象必须和一定的对象输入输出流联系起来,通过对象输出流将对象状态保存下来,再通过对象输入流将对象状态恢复

序列化工具

在java.io包中,提供了ObjectInputStream和ObjectOutputStream,将数据流功能扩展至可读写对象。在ObejctInputStream输出流,将数据流功能扩展至可读写对象。在ObjectInputStream中用readObejct()方法可以直接读取一个对象,在ObejctOutputStream中用writeObeject()方法可以直接将对象保存到输出流。

ObjectOutputStream

是一个处理流,必须建立在其他节点流的基础上

  1. FileOutputStream fileout=new FileOutputStream("hehe.txt");
  2. ObjectOutputStream objectOut=new ObjectOutputStream(fileout);

writeObject()方法将对象写入流中。所有的对象(String和数组)都可以通过这个方法写入。

  1. objectOut.writeObject("hello");
  2. objectOut.writeObject(new Date());

构造方法两个:

QQ图片20161129155435.png-4.6kB

ObjectInputStream

是一个处理流,必须建立在其他节点流的基础上.对以前使用的ObjectInputStream写入的数据进行反序列化。

  1. FileInputStream fileIn=new FileInputStream("hehe.txt");
  2. ObjectInputStream objectIn=new ObjectInputStream(fileIn);

readObject()方法用于从流中读取对象。注意Obejct的强制类型转换

  1. String s=(String)objectIn.readObject(objectIn);
  2. Date date=(Date)objectIn.readObject(objectIn);

QQ图片20161129155435.png-4.5kB

实例

  1. class Student implements Serializable {
  2. private int id;
  3. String name;
  4. String sex;
  5. int age;
  6. String department;
  7. public Student(int id, String name, String sex, int age, String department) {
  8. this.id = id;
  9. this.name = name;
  10. this.sex = sex;
  11. this.age = age;
  12. this.department = department;
  13. }
  14. public String toString() {
  15. String string = id + " " + name + " " + sex + " " + age + " " + department;
  16. return string;
  17. }
  18. };
  19. public class RuntimeTest {
  20. public static void main(String[] args) {
  21. Student stu0 = new Student(11, "XQF", "male", 34, "CS");
  22. Student stu1 = new Student(11, "WLY", "male", 34, "CS");
  23. try {
  24. FileOutputStream fileOut = new FileOutputStream("D:\\workspace\\JavaCode\\JavaClassicClass\\src\\com\\exercise\\test\\test.txt");
  25. ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
  26. objectOut.writeObject(stu0);
  27. objectOut.writeObject(stu1);
  28. objectOut.close();
  29. FileInputStream fileIn = new FileInputStream("D:\\workspace\\JavaCode\\JavaClassicClass\\src\\com\\exercise\\test\\test.txt");
  30. ObjectInputStream objectIn = new ObjectInputStream(fileIn);
  31. Student stu2 = (Student) objectIn.readObject();
  32. Student stu3 = (Student) objectIn.readObject();
  33. System.out.println(stu2);
  34. System.out.println(stu3);
  35. } catch (Exception e) {
  36. e.printStackTrace();
  37. }
  38. }
  39. }

确实实现了功能,但是想看看文件内的具体数据,。以对象为单位写入文件存储怕是根本见不到文件内容的真面目。

串行化(序列化)只能保存对象的非静态变量,不能保存任何的成员方法和静态成员变量。而且序列化保存的只是变量的值,对于变量的任何修饰符都是没有办法保存的。对于某些类型对象,其状态是瞬时的,这样的对象也是没有办法保存状态的,对于这些字段,我们必须使用transient进行说明。

定制序列化

缺省的序列化首先写入数据和类字段信息,然后按照名称的上升排列顺序写入数据。如果要想明确的控制这些数值的写入顺序和写入种类,必须自定义读取数据流的方式,就是在类的定义中重写writeObject()方法和readObject()方法。

  1. class Student implements Serializable {
  2. private int id;
  3. String name;
  4. String sex;
  5. int age;
  6. String department;
  7. public Student(int id, String name, String sex, int age, String department) {
  8. this.id = id;
  9. this.name = name;
  10. this.sex = sex;
  11. this.age = age;
  12. this.department = department;
  13. }
  14. public String toString() {
  15. String string = id + " " + name + " " + sex + " " + age + " " + department;
  16. return string;
  17. }
  18. private void writeObject(ObjectOutputStream out) {
  19. try {
  20. out.writeInt(id);
  21. out.writeUTF(name);
  22. out.writeUTF(sex);
  23. out.writeInt(age);
  24. out.writeUTF(department);
  25. } catch (IOException e) {
  26. e.printStackTrace();
  27. }
  28. }
  29. private void readObject(ObjectInputStream in) throws IOException {
  30. id = in.readInt();
  31. name = in.readUTF();
  32. sex = in.readUTF();
  33. age = in.readInt();
  34. department = in.readUTF();
  35. }
  36. };
  37. public class RuntimeTest {
  38. public static void main(String[] args) {
  39. Student stu0 = new Student(11, "XQF", "male", 34, "CS");
  40. Student stu1 = new Student(11, "WLY", "male", 34, "CS");
  41. try {
  42. FileOutputStream fileOut = new FileOutputStream("D:\\workspace\\JavaCode\\JavaClassicClass\\src\\com\\exercise\\test\\test.txt");
  43. ObjectOutputStream objectOut = new ObjectOutputStream(fileOut);
  44. objectOut.writeObject(stu0);
  45. objectOut.writeObject(stu1);
  46. objectOut.close();
  47. FileInputStream fileIn = new FileInputStream("D:\\workspace\\JavaCode\\JavaClassicClass\\src\\com\\exercise\\test\\test.txt");
  48. ObjectInputStream objectIn = new ObjectInputStream(fileIn);
  49. Student stu2 = (Student) objectIn.readObject();
  50. Student stu3 = (Student) objectIn.readObject();
  51. System.out.println(stu2);
  52. System.out.println(stu3);
  53. objectIn.close();
  54. } catch (Exception e) {
  55. e.printStackTrace();
  56. }
  57. }
  58. }

老实说UTF没有作用呀,文件打开还是乱码,。,。可能本身就看不见。

国际惯例:总结

好像一切都说得通了,这里的序列化的作用使得自定义类对象化身为流,,,,于是可以将流写入文件内保存,同样也可以用于网络上信息的传输。再从文件中取出流转换为对象就可以了。注意字节流

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注