java中io流(二)

序列化与反序列化:

1.概念:

序列化:将对象的状态存储到特定介质的过程。也就是将对象的状态转换为可传输(流)的过程!

序列化 -------》 写入(输出流)

反序列化:从特定存储介质中读取数据并重新构建成对象的过程!也就是把流解析成对象的方式!

反序列化------》读取 (输入流)

2.关键对象

  • 序列化:ObjectOutputStream,输出流对象.writeObject(自定义类的对象/集合);

  • 反序列化:ObjectInputStream,输入流对象.readObject()

  • 注意:序列化必须要实现Serializable接口,反序列化要进行强制类型转换,因为返回的是一个Object类型的对象!

3.代码如下

//学生类:实现了序列化接口Serializable
public class Student implements Serializable{
	
	private int id;
	private String name;
	private String pwd;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	
	public Student() {
		
	}
	
	public Student(int id,String name,String pwd ) {
		this.id=id;
		this.name=name;
		this.pwd=pwd;
	}

	/**
	 * 重写toString 方法
	 */
	public String toString() {
		return "学号:" + id + ", 姓名:" + name + ", 密码:" + pwd;
	}
	
}

//测试类:
public class Test {
	public static void main(String[] args) {
		//创建集合对象
		ArrayList <Student> list=new ArrayList<Student>();
		//创建学生类对象
		Student stu1=new Student(11,"张三","123456");
		Student stu2=new Student(12,"李四","024966");
		Student stu3=new Student(13,"王五","386436");
		
		//添加集合对象
		list.add(stu1);
		list.add(stu2);
		list.add(stu3);
		//声名序列化对象,
		ObjectOutputStream oos=null;
		ObjectInputStream ois=null;
		try {
			//1.序列化
			//创建序列化对象输出流,写入数据
			oos=new ObjectOutputStream(new FileOutputStream("学生.txt"));
			
			
			//写入对象(集合)
			oos.writeObject(list);
			
			
			//2.反序列化
			//创建反序列化对象输入流,读取数据
			ois=new ObjectInputStream(new FileInputStream("学生.txt"));
			
			//读取集合中的对象,得到的是Object类型
			Object obj=ois.readObject();
			
			//将集合中的obj类型强制转换成Student类型
			ArrayList<Student> stuList=(ArrayList<Student>) obj;
			
			//循环读取集合中的对象
			for (int i = 0; i < list.size(); i++) {
				Student stu=stuList.get(i);
				System.out.println(stu);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				//关闭流
				ois.close();
				oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
}



输出结果:

注意:

  • 如果出于安全考虑,某些属性要限制不能序列化,就需要使用transient关键字修饰属性!
  • 如果在向文件中使用序列化机制写入多个对象,那么反序列化恢复对象时,必须按照写入的顺序读取。
  • 如果一个可序列化的类,有多个父类(包括直接或者间接父类),则这些父类要么是可序列化的,要么有无参构造器,否则会抛出异常!

4.对象引用的序列化:

  • 所有保存到磁盘中的对象都有一个序列号
  • 当程序视图序列化一个对象时,将会检查是否已经序列化,只有序列化后的对象才能被转换成字节序列输出,否则报NotSerializableException异常
  • 如果对象已经被序列化,则程序直接输出一个序列化编号,而不再重新序列化。

猜你喜欢

转载自blog.csdn.net/JAVA52Lin/article/details/83507539