首页 > 代码库 > java 21 - 13 IO流之序列化和反序列化
java 21 - 13 IO流之序列化和反序列化
序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输。对象 -- 流数据(ObjectOutputStream)
构造方法:ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream
反序列化流:把文本文件中的流对象数据或者网络中的流对象数据还原成对象。流数据 -- 对象(ObjectInputStream)
构造方法:ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream
由于序列化和反序列化的操作对象是类,所以先创建个类:
1 package zl_Copy; 2 3 import java.io.Serializable; 4 5 /* 6 //NotSerializableException:类未序列化异常,所以所要序列话的类要实现Serializable接口 7 8 */ 9 public class Animal implements Serializable{10 11 private static final long serialVersionUID = 6425500536266476858L;12 private String name;13 //private int age;
* private transient int age;14 15 16 public Animal() {17 super();18 // TODO Auto-generated constructor stub19 }20 21 22 public Animal(String name, int age) {23 super();24 this.name = name;25 this.age = age;26 }27 28 29 public String getName() {30 return name;31 }32 33 34 public void setName(String name) {35 this.name = name;36 }37 38 39 public int getAge() {40 return age;41 }42 43 44 public void setAge(int age) {45 this.age = age;46 }47 48 49 @Override50 public String toString() {51 return "Animal [name=" + name + ", age=" + age + "]";52 }53 54 55 }
实现类:
1 public class ObjectStreamDemo { 2 3 public static void main(String[] args) throws IOException, ClassNotFoundException { 4 //由于序列化的对象是个类,所以要首先创建一个类 5 //序列化方法 6 //write(); 7 //反序列化 8 read(); 9 }10 11 private static void read() throws IOException, IOException, ClassNotFoundException {12 // 创建反序列化对象13 //ObjectInputStream(InputStream in) 创建从指定 InputStream 读取的 ObjectInputStream14 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("test.txt"));15 16 //还原序列化对象,不管什么类,反正它父类是Object17 Object o = ois.readObject();18 19 //释放资源20 ois.close();21 //输出结果到控制台看看22 System.out.println(o);23 //Animal [name=萨摩耶, age=2]24 25 }26 27 private static void write() throws IOException {28 //创建序列化对象29 //ObjectOutputStream(OutputStream out) 创建写入指定 OutputStream 的 ObjectOutputStream。30 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("test.txt"));31 32 //创建所要序列化的类的对象33 Animal a = new Animal("萨摩耶",2);34 35 //写入序列化对象中,注意,写入的是类36 oos.writeObject(a);37 38 //释放资源39 oos.close();40 41 //java.io.NotSerializableException42 //NotSerializableException:类未序列化异常,所以所要序列话的类要实现Serializable接口43 }44 45 }
注意:
private static final long serialVersionUID = 6425500536266476858L;:
为什么要写这个?如果不写这个,若是更改了类里面的变量,如:
1 private int age;2 改为:3 int age;
若是这样更改了以后,就必须重新进行序列化,不然就会出现错误:
java.io.InvalidClassException: cn.itcast_07.Person; local class incompatible: stream classdesc serialVersionUID = -2071565876962058344, local class serialVersionUID = -8345153069362641443
为什么会有问题呢?
Person类实现了序列化接口,那么它本身也应该有一个标记值。
先把这个标记值假设是100。
开始的时候:
Person.class -- id=100
wirte数据: oos.txt -- id=100
read数据: oos.txt -- id=100
更改了age以后:
Person.class -- id=200
wirte数据: oos.txt -- id=100
read数据: oos.txt -- id=100
我们在实际开发中,可能还需要使用以前写过的数据,但是不能重新写入。
所以,我们要让这个id值在java文件中设为一个固定的值,这样,修改文件的时候,这个id值就不会发生改变。
方法是:看到类名处有黄色警报线,点击鼠标即可。
private transient int age;
一个类中可能有很多的成员变量,但是有些变量不想进行序列化。
方法:使用transient关键字声明不需要序列化的成员变量
java 21 - 13 IO流之序列化和反序列化