• 10-2、对象的序列化和反序列化


    一、序列化、反序列化到底是什么?

    • (1) 名词解释
      对象的序列化 : 把 Java 对象转换为字节序列并存储至一个储存媒介的过程。
      对象的反序列化:把字节序列恢复为 Java 对象的过程。

    • (2) 序列化详细解释
      对象的序列化涉及三个点关键点:Java 对象、字节序列、存储。

      1. Java 对象的组成?
        Java 对象包含变量与方法。但是序列与反序列化仅处理 Java 变量而不处理方法,序列与反序列化仅对数据进行处理。
      1. 什么是字符序列?
        字符序列是两个词,字符是在计算机和电信领域中,字符(Character)是一个信息单位。数学上,序列是被排成一列的对象(或事件)。
        《字符-维基百科》,《序列-维基百科》说白了就是连续排列的多个字符的集合。类似于 1A165613246546
      1. 存储
        字符序列需要保存到一个地方,可以是硬盘也可以是内存。
        简单说法是:序列化把当前对象信息保存下来。反序列化刚好相反的操作。

    二、Java 对象与 Java 对象序列化的区别?

    Java 对象存在的前提必须在 JVM 运行期间存在,如果想在 JVM 非运行的情况下或者在其他机器 JVM 上获取指定 Java 对象,在现有 Java 对象的机制下都不可能完成。
    与 Java 对象不同的是,如果对 Java 对象执行序列化操作,因为原理是把 Java 对象信息保存到存储媒介,所以可以在以上 Java 对象不可能存在的两种情况下依然可以使用 Java对象。

    三、为什么要使用序列化、反序列化?

    根据以上对序列化、反序列化的理解,这个疑问可以翻译成,为什么需要把对象信息保存到存储媒介中并之后读取出来?
    因为二中的解释,开发中有在JVM非运行的情况下或者在其他机器JVM上获取指定Java对象的需求。

    四、当对一个对象实现序列化时,究竟发生了什么?

    在没有序列化前,每个保存在堆(Heap)中的对象都有相应的状态(state),即实例变量(instance ariable)比如:

    java 代码
    Foo myFoo = new Foo();
    myFoo .setWidth(37);
    myFoo.setHeight(70);

       当 通过下面的代码序列化之后,MyFoo对象中的width和Height实例变量的值(37,70)都被保存到foo.ser文件中,这样以后又可以把它 从文件中读出来,重新在堆中创建原来的对象。当然保存时候不仅仅是保存对象的实例变量的值,JVM还要保存一些小量信息,比如类的类型等以便恢复原来的对 象。

    java 代码
    FileOutputStream fs = new FileOutputStream("foo.ser");
    ObjectOutputStream os = new ObjectOutputStream(fs);
    os.writeObject(myFoo);

    五、序列化与反序列化实例

    用于序列化和反序列化的 Java 对象

    package serializable;
    
    import java.io.Serializable;
    
    /**
     * 
     * @Description: TODO:创建学生类,用于序列化
     * @author pengguozhen
     * @date 2017年9月4日 下午3:43:41
     * 序列化 该类,该类必须实现序列化的接口
     */
    public class Student implements Serializable{
    
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	private String name;
    	private char sex;
    	private int year;
    	private double gpa;
    
    	public Student() {
    
    	}
    
    	public Student(String name, char sex, int year, double gpa) {
    		this.name = name;
    		this.sex = sex;
    		this.year = year;
    		this.gpa = gpa;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public void setSex(char sex) {
    		this.sex = sex;
    	}
    
    	public void setYear(int year) {
    		this.year = year;
    	}
    
    	public void setGpa(double gpa) {
    		this.gpa = gpa;
    	}
    
    	public String getName() {
    		return this.name;
    	}
    
    	public char getSex() {
    		return this.sex;
    	}
    
    	public int getYear() {
    		return this.year;
    	}
    
    	public double getGpa() {
    		return this.gpa;
    	}
    }
    

    进行序列化和反序列化

    package serializable;
    
    import java.io.*;
    
    /**
     * 
     * @Description: TODO:将 student 类进行序列化和反序列化
     * @author pengguozhen
     * @date 2017年9月4日 下午4:03:38
     */
    public class UseStudent {
    
    	public static void main(String[] args) {
    		Student st = new Student("Tom", 'M', 20, 3.6);
    		String dir = System.getProperty("user.dir");//获取当前项目的根路径
    		File file = new File(dir+"\src\serializable\student.txt");
    		try {
    			file.createNewFile();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    		try {
    			// Student对象序列化过程
    			FileOutputStream fos = new FileOutputStream(file);
    			ObjectOutputStream oos = new ObjectOutputStream(fos);
    			oos.writeObject(st);
    			oos.flush();
    			oos.close();
    			fos.close();
    
    			// Student对象反序列化过程
    			FileInputStream fis = new FileInputStream(file);
    			ObjectInputStream ois = new ObjectInputStream(fis);
    			Student st1 = (Student) ois.readObject();
    			System.out.println("name = " + st1.getName());
    			System.out.println("sex = " + st1.getSex());
    			System.out.println("year = " + st1.getYear());
    			System.out.println("gpa = " + st1.getGpa());
    			ois.close();
    			fis.close();
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		} catch (IOException e) {
    			e.printStackTrace();
    		}
    	}
    }

    六、serialVersionUID 在序列化时的作用

    简单来说,Java 的序列化机制是通过在运行时判断类的 serialVersionUID 来验证版本一致性的。在进行反序列化时,JVM 会把传来的字节流中的 serialVersionUID 与本地相应实体(类)的 serialVersionUID 进行比较,如果相同就认为是一致的,可以进行反序列化,否则就会出现序列化版本不一致的异常。(InvalidCastException)

  • 相关阅读:
    谈谈Vue.js——vue-resource全攻略
    XStream(xml/bean转换)
    Notepad++ xml/json格式化
    秒杀系统架构分析与实战
    Spring事务管理
    小程序思维导图(一)
    小程序思维导图(二)
    轻松搭建持续集成工具jenkins
    rep stos dword ptr es:[edi]
    关于dword ptr 指令
  • 原文地址:https://www.cnblogs.com/pengguozhen/p/14779580.html
Copyright © 2020-2023  润新知