(21)IO流之对象的序列化和反序列化流ObjectOutputStream和ObjectInputStream

当创建对象时,程序运行时它就会存在,但是程序停止时,对象也就消失了.但是如果希望对象在程序不运行的情况下仍能存在并保存其信息,将会非常有用,对象将被重建并且拥有与程序上次运行时拥有的信息相同。可以使用对象的序列化。

 对象的序列化:   将内存中的对象直接写入到文件设备中

 对象的反序列化: 将文件设备中持久化的数据转换为内存对象

基本的序列化由两个方法产生:一个方法用于序列化对象并将它们写入一个流,另一个方法用于读取流并反序列化对象。

ObjectOutput

writeObject(Object obj)

          将对象写入底层存储或流。

ObjectInput

readObject()

          读取并返回对象。

下面介绍的就是他们的实现子类:ObjectOutputStreamObjectInputStream

对象的输入输出流:对象的输入输出流的主要作用是:用于对象信息的读写,对象信息一旦写到文件上那么对象的信息就可以持久化

对象的输出流

ObjectOutputStream 主要用用于输出对象

ObjectOutputStream的使用步骤

1、找到目标文件

2、建立数据的输出流通道,需要准备一个FileOutputStream流

3、建立对象的输出流通道

4、把对象写出去

5、关闭资源

使用反序列化,就是使用流ObjectInputStream流,完全和上面相反的步骤。

对象输入输出流使用需要注意的细节:

1、如果对象需要被写出到文件上,那么对象所属的类必须要实现Serializable接口,Serializable接口没有任何的方法,是一个标志接口。

2、对象的反序列化和对象的克隆,创建对象的时候,并不会调用构造方法。

3serialVersionUID是用于记录class文件的版本信息的,serialVersionUID这个数字是通过一个类的类名,成员,包名,工程名算出来的一个数字。

4、使用ObjectInputStream反序列化的时候,ObjectInputStream会先读取文件中的serialVersionUID与本地的serialVersionUID对比,如果不一致反序列化失败

5、如果反序列化的时候可能会修改类的成员,那么最好一开始就给这个类,指定一个serialVersionUID,如果一个类已经指定了serialVersionUID,然后在序列化和反序列化的时候,jvm都不会自己计算这个classserialVersionUID了。这样就不怕无法序列化和反序列化了。点击累前面的黄色箭头,添加一个serialVersionUID

6、如果一个对象的某个数据不想序列化到硬盘上,可以使用关键字transient修饰

7、如果一个类,维护了另外一个类的引用,另外一个类,也需要实现Serializable接口。如果无法修改这个类的源码,可以给这个类创建一个可序列化的子类。如果这个类是final的也就是不可以继承的。那么就在使用trancint关键字,或者是指定serialVersionUID

下面是一个简单的例子:

 1 class Address implements Serializable
 2 {
 3     String country;
 4     String city;
 5     
 6     public Address(String country, String city)
 7     {
 8         this.country = country;
 9         this.city = city;
10     }
11 }
12 
13 
14 class User implements Serializable{
15 
16     private static final long serialVersionUID = -1241976087141510667L;
17 
18     String userName ;
19     
20     String password ;
21 
22     transient int age;
23     
24     Address address;
25     
26     public User(String name, String pass)
27     {
28         this.userName = name;
29         this.password = pass;
30     }
31     
32     public User(String name, String pass, int age, Address address)
33     {
34         this.userName = name;
35         this.password = pass;
36         this.age = age;
37         this.address = address;
38     }
39     
40     @Override
41     public String toString()
42     {
43         return "用户名:"+this.userName+" 密码:"+this.password+" 年龄:"+this.age+" 地址:"+this.address.city;
44     }
45 }
46 
47 
48 public class Demo3
49 {
50     public static void main(String[] args) throws IOException, ClassNotFoundException
51     {
52         //把user的信息持久化
53         /*User user = new User("admin", "123");
54         System.out.println(user);
55 */        
56          writeObj();
57          readObj();
58         
59     }
60     
61     //把文件中的对象信息取出来
62     public static void readObj() throws IOException, ClassNotFoundException
63     {
64         File file = new File("D:\users.txt");
65         FileInputStream fileInputStream = new FileInputStream(file);
66         //建立对象的输入流对象
67         ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
68         //读取独对象信息
69         User user = (User) inputStream.readObject();    //创建对象坑定要依赖对象所属的class文件
70         System.out.println(user);
71     }
72     
73     
74     //定义方法把对象的信息写到硬盘上------>对象的序列化
75     public static void writeObj() throws IOException
76     {
77         Address address = new Address("China", "Anhui");
78         User user = new User("admin", "123", 15, address);
79         
80         //1、找到目标文件
81         File file= new File("D:\users.txt");
82         //建立数据的输出流对象
83         FileOutputStream fileOutputStream = new FileOutputStream(file);
84         //建立对象的输出流对象
85         ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
86         //把对象写出去
87         objectOutputStream.writeObject(user);//序列化house的内容 是给JVM看的 一般我们是看不懂的
88         //关闭资源
89         objectOutputStream.close();
90     }
91     
92 }
View Code
原文地址:https://www.cnblogs.com/OliverZhang/p/6026200.html