Java面向对象
Java异常
Java数组
Java常用类
Java集合
Java IO流
Java线程
Java反射
Socket编程
Java注解开发
Java GoF设计模式
HashMap
Java内存模型
Java线性表

Java对象输入输出流

对象序列化:把一个对象转换为01二进制

对象反序列化:把一组01二进制转换为对象

ObjectOutputStream类可以实现对象序列化, 把对象转换为01序列保存到文件中

ObejctInputStream类实现对象反序列化,从文件中读取01序列转换为对象

注意:

对象序列化/反序列化的前提是对象的类必须实现Serializable接口, 该接口是一个标志接口,没有任何方法,只是告诉编译器这个类的对象可以序列化。

package com.wkcto.chapter06.objectstream;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;

/**
 * 使用ObjectOutputStream可以实现对象的序列化, 把对象的01序列保存到文件中
 * 
 * @author 蛙课网
 *
 */
public class Test01 {
	public static void main(String[] args) throws IOException {
		//创建Person对象
		Person lisi = new Person("lisi", 18);
		
		//把lisi对象序列化, 就是把lisi对象保存到文件中
		OutputStream out = new FileOutputStream("d:/obj.txt");
		ObjectOutputStream oos = new ObjectOutputStream(out);
		
		oos.writeObject(lisi); 		//对象序列化
		
		oos.close();
		
	}
}
package com.wkcto.chapter06.objectstream;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;

/**
 * 使用ObjectInputStream类实现对象的反序列化,
 * 		就是从文件中把保存的对象读取出来
 * 
 * @author 蛙课网
 *
 */
public class Test02 {

	public static void main(String[] args) throws IOException, ClassNotFoundException {
		InputStream in = new FileInputStream("d:/obj.txt");
		ObjectInputStream ois = new ObjectInputStream(in);
		
		Object obj = ois.readObject();  	//从文件中读取一个对象, readObject()方法的返回值是Object类型的
		//文件中实际存储的是Person对象, 使用obj引用指向Person对象
		
		System.out.println( obj ); 		//实际上调用的是Person对象的toString()方法
		ois.close();
		
		/*
		 * 在对象序列化之后 ,即把对象已经保存到文件中了,  又在Person类中添加了一个字段,修改了Person类结构,
		 * 	再进行反序列化时, 出现了异常:
		 *  java.io.InvalidClassException:
		 *  	com.wkcto.chapter06.objectstream.Person; local class incompatible: 
		 * 		stream classdesc serialVersionUID = 3479771803741762411, 
		 * 		local class serialVersionUID = 1549311491347595402
		 * 分析原因:
		 * 		流中类的描述信息中 serialVersionUID的值与本地字节码文件中 serialVersionUID字段的值不相等引发的异常
		 * 
		 * 		当类Person实现了Serializable接口后, 系统会自动的在Person类中增加一个serialVersionUID序列化版本号字段
		 * 		在lisi对象序列化时, serialVersionUID字段的值是: 3479771803741762411
		 * 		当序列化后, 又在Person类添加了gender字段, 编译后,在字节码文件中重新生成了一个serialVersionUID的值:1549311491347595402
		 * 		在进行反序列化时, 系统会检查流中serialVersionUID序列化版本号字段与本地字节码文件中serialVersionUID字段的值是否一样
		 * 			如果相等就认为是同一个类的对象, 如果这个serialVersionUID序列化版本号字段的值不相等,就认为是不同类的对象
		 * 解决方法:
		 * 		保证反序列化时流中serialVersionUID字段 的值,与本地字节码文件中serialVersionUID字段的值相等即可
		 * 		可以在Person类实现了Serializable接口后, 手动的添加一个serialVersionUID字段 
		 */
		
	}

}
package com.wkcto.chapter06.objectstream;

import java.io.Serializable;
/**
 * Person类的对象要想序列化, Person类必须实现Serializable接口
 * 		Serializable接口是一个标志接口,没有任何方法
 * @author 蛙课网
 *
 */
public class Person implements Serializable{
	String  name;
	int age;
	
	String gender; 		//性别
	
	//手动的添加序列化版本号字段
	 private static final long serialVersionUID = -1345649873215667710L;
	
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]";
	}


	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
}