您的位置:首页 > 编程语言 > Java开发

Java学习笔记之IO(十三):对象的序列化和反序列化

2017-10-11 16:23 836 查看
package com.io.g_sequence;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import org.junit.Test;

/*

对象的输入输出流:主要作用是写对象的信息和读取对象的信息;

对象的输出流:ObjectOutputStream,将对象数据写出到硬盘上(对象的序列化)
使用步骤:
1、找到目标文件
2、建立数据的输出通道
3、建立对象的输出流
4、写出对象数据
5、关闭资源

对象的输入流:ObjectInputStream,从硬盘上读取对象数据(对象的反序列化)
使用步骤:
1、找到目标文件
2、建立数据的输入通道
3、建立对象的输入流
4、读取对象数据
5、关闭资源

对象的输入输出流注意事项;
1、如果对象需要被写出到文件上,那么对象所属的类必须要实现Serializable接口;该接口没有任何方法,是一个标识接口;
2、对象的反序列化创建对象的时候并不会调用构造方法;
3、如果反序列化的时候,User类多了一个字段 int age;那么就会出现异常,异常信息为:
java.io.InvalidClassException: com.io.g_sequence.User; local class incompatible: stream classdesc
serialVersionUID = 8045794779143966462, local class serialVersionUID = 3828153352226528185;
该异常信息表示:本地的class文件的 serialVersionUID 号与对象输入流里面的 serialVersionUID 号不一致;
serialVersionUID 是用于记录class文件的版本信息的,serialVersionUID 这个数字是根据类的类名、成员、包名、
工程名算出的一个数字;
4、使用ObjectInputStream反序列化的时候,ObjectInputStream会先读取文件中的serialVersionUID,
然后与本地class文件的serialVersionUID进行对比,如果这两个id不一致,那么反序列化失败;
5、如果序列化和反序列化的时候可能会修改类的成员,那么最好一开始就给这个类指定一个serialVersionUID;如果一个类
已经指定了serialVersionUID,那么在序列化和反序列化的时候,jvm都不会再去算这个class的serialVersionUID了;
6、如果一个对象的某个数据不想被序列化到硬盘上,可以使用关键字 transient 修饰;
7、如果一个类中维护了另外一个类的引用,那么另外一个类也需要实现 Serializable 接口;

*/

// 如果User类中维护了Address类,那么序列化和反序列化的时候Address类也要实现 Serializable 接口;
class Address{

String city;
String controy;

public Address(String city, String controy) {
this.city = city;
this.controy = controy;
}

}

class User implements Serializable{

String username;
String password;
//	transient int age; 	// transient:透明

public User(String username, String password) {
this.username = username;
this.password = password;
}

@Override
public String toString() {
return "User [username=" + username + ", password=" + password + "]";
}

}

public class Demo3 {

// 对象的信息在程序执行结束就会删除;
@Test
public void test1(){
User user = new User("张三", "123");
System.out.println(user);
}

// 使用对象的输出流将对象信息持久化保存;
4000
// 把对象的信息写到硬盘上,叫做对象的序列化;
// 序列化的时候不光将对象信息写入到硬盘上,同时还会将对象所属的class文件的serialVersionUID号,也记录到硬盘上;
@Test
public void writeObj() throws IOException{
// 定义对象信息
User user = new User("张三", "123");
// 找到目标文件
File file = new File("D:\\user.obj");
// 建立数据的输出通道
FileOutputStream out = new FileOutputStream(file);
// 建立对象的输出流对象
ObjectOutputStream object = new ObjectOutputStream(out);
// 写出对象数据
object.writeObject(user);
// 关闭资源
object.close();
}

// 把对象信息从硬盘上读取出来,叫做对象的反序列化;
@Test
public void readObj() throws Exception{
// 找到目标文件
File file = new File("D:\\user.obj");
// 建立数据的输入通道
FileInputStream in = new FileInputStream(file);
// 建立对象的输入流
ObjectInputStream object = new ObjectInputStream(in);
// 读取对象数据
User user = (User)object.readObject(); // 创建对象依赖对象所属的class文件
System.out.println(user);
// 关闭资源
object.close();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: