序列化流(ObjectOutputStream、ObjectInputStream)

1、序列化流(ObjectOutputStream)

 1 package demo10.objstream;
 2 
 3 /*
 4     java.io.ObjectOutputStream extends OutputStream
 5     ObjectOutputStream:对象的序列化流
 6     作用:把对象以流的方式写入到文件中保存
 7 
 8     构造方法:
 9         ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream。
10         参数:
11             OutputStream out:字节输出流
12     特有的成员方法:
13         void writeObject(Object obj) 将指定的对象写入 ObjectOutputStream。
14 
15     使用步骤:
16         1.创建ObjectOutputStream对象,构造方法中传递字节输出流
17         2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
18         3.释放资源
19  */
20 
21 import java.io.FileNotFoundException;
22 import java.io.FileOutputStream;
23 import java.io.IOException;
24 import java.io.ObjectOutputStream;
25 
26 public class demo01objout {
27     public static void main(String[] args) throws IOException {
28         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt"));
29         Person p=new Person("kelvin",18);
30         oos.writeObject(p);
31         oos.close();
32     }
33 }

2、反序列化流(ObjectInputStream)

 1 package demo10.objstream;
 2 
 3 /*
 4     java.io.ObjectInputStream extends InputStream
 5     ObjectInputStream:对象的反序列化流
 6     作用:把文件中保存的对象,以流的方式读取出来使用
 7 
 8     构造方法:
 9         ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream。
10         参数:
11             InputStream in:字节输入流
12     特有的成员方法:
13         Object readObject() 从 ObjectInputStream 读取对象。
14 
15     使用步骤:
16         1.创建ObjectInputStream对象,构造方法中传递字节输入流
17         2.使用ObjectInputStream对象中的方法readObject读取保存对象的文件
18         3.释放资源
19         4.使用读取出来的对象(打印)
20 
21      readObject方法声明抛出了ClassNotFoundException(class文件找不到异常)
22      当不存在对象的class文件时抛出此异常
23      反序列化的前提:
24         1.类必须实现Serializable
25         2.必须存在类对应的class文件
26  */
27 
28 import java.io.*;
29 
30 public class demo01objin {
31     public static void main(String[] args) throws IOException, ClassNotFoundException {
32         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt"));
33         Object o = ois.readObject();
34         ois.close();
35         Person p = (Person) o;
36         System.out.println(p.getName() + " " + p.getAge());
37     }
38 }

Person类

 1 package demo10.objstream;
 2 
 3 import java.io.Serializable;
 4 
 5 /*
 6     序列化和反序列化的时候,会抛出NotSerializableException没有序列化异常
 7     类通过实现 java.io.Serializable 接口以启用其序列化功能。未实现此接口的类将无法使其任何状态序列化或反序列化。
 8     Serializable接口也叫标记型接口
 9         要进行序列化和反序列化的类必须实现Serializable接口,就会给类添加一个标记
10         当我们进行序列化和反序列化的时候,就会检测类上是否有这个标记
11             有:就可以序列化和反序列化
12             没有:就会抛出 NotSerializableException异常
13 
14 
15     static关键字:静态关键字
16         静态优先于非静态加载到内存中(静态优先于对象进入到内存中)
17         被static修饰的成员变量不能被序列化的,序列化的都是对象
18         private static int age;
19         oos.writeObject(new Person("kelvin",18));
20         Object o = ois.readObject();
21         Person{name='kelvin', age=0}
22 
23     transient关键字:瞬态关键字
24         被transient修饰成员变量,不能被序列化
25         private transient int age;
26         oos.writeObject(new Person("kelvin",18));
27         Object o = ois.readObject();
28         Person{name='kelvin', age=0}
29 
30  */
31 
32 public class Person implements Serializable {
33     private String name;
34     private int age;
35 
36     public Person() {
37     }
38 
39     public Person(String name, int age) {
40         this.name = name;
41         this.age = age;
42     }
43 
44     @Override
45     public String toString() {
46         return "Person{" +
47                 "name='" + name + '\'' +
48                 ", age=" + age +
49                 '}';
50     }
51 
52     public String getName() {
53         return name;
54     }
55 
56     public void setName(String name) {
57         this.name = name;
58     }
59 
60     public void setAge(int age) {
61         this.age = age;
62     }
63 
64     public int getAge() {
65         return age;
66     }
67 }
# 注:在序列化对象时,由于该对象所属的类实现了Serializable接口,所以该类在编译时会在.class文件中保存SerialVersionUID=xxx标识,如果类定义发生改变,SerialVersionUID也会改变。并且序列化对象时,内部会携带该标识,当反序列化时候,判断如果反序列化的对象内部的SerialVersionUID和.class文件内部保存的SerialVersionUID相同反序列化成功,否则抛出InvalidClassException异常。

解决方式:
在定义类时候手动定义SerialVersionUID。
格式为:private static final long serialVersionUID=xxL

3、练习(序列化集合)

 1 package demo10.objstream;
 2 
 3 import java.io.*;
 4 import java.util.ArrayList;
 5 
 6 public class test {
 7     public static void main(String[] args) throws IOException, ClassNotFoundException {
 8 //        output();
 9         input();
10     }
11 
12     private static void input() throws IOException, ClassNotFoundException {
13         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("list.txt"));
14         Object o = ois.readObject();
15         ArrayList<Person> list = (ArrayList) o;
16         for (Person person : list) {
17             System.out.println(person);
18         }
19         ois.close();
20 
21     }
22 
23     private static void output() throws IOException {
24         ArrayList<Person> list = new ArrayList<>();
25         list.add(new Person("kelvin", 23));
26         list.add(new Person("jack", 18));
27         list.add(new Person("siri", 34));
28 
29         ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.txt"));
30         oos.writeObject(list);
31         oos.close();
32     }
33 }

 

posted @ 2020-08-18 09:52  佛祖让我来巡山  阅读(376)  评论(0编辑  收藏  举报

佛祖让我来巡山博客站 - 创建于 2018-08-15

开发工程师个人站,内容主要是网站开发方面的技术文章,大部分来自学习或工作,部分来源于网络,希望对大家有所帮助。

Bootstrap中文网