Java中序列化与反序列化的理解

这两天在看有关序列化与反序列化的内容,大概知道了序列化与反序列化的作用,特此记录下,记录的同时 希望对迷惑这一块内容的同学有所帮助 。另外参考文章如下,讲的很仔细。原文地址
序列化与反序列化的概念

  • 序列化:将对象序列化为字节序列的过程称为序列化.
  • 反序列化:将字节序列转换为反序列化对象的过程称为反序列化
  • Serializable接口:没有任何抽象方法需要实现,只要对象实现了这个接口,就可以对该对象进行序列化与反序列化操作.如果没有指明serialVersionUID,那么编译器在将java文件加载为class字节码的过程中会默认添加一个随机serialVersionUID属性.

序列化与反序列化的作用
序列化与反序列化一般有2个作用:

  1. 数据持久化:简而言之就是将数据存储到磁盘文件的时候,需要将对象序列化存入磁盘中. 举个最常用的例子:Tomcat中存储session信息,当10W个人同时访问Web服务器,需要将10W个session同时存入tomcat内存中,但是tomcat的内容是有限制的,那么如何解决这一问题那?就是通过将一些不活动但是未超过生命周期的sesssion序列化存储到磁盘中,当需要用到的时候反序列化读取出来。
  2. 网络传输中:当分布式系统中需要传输同一个对象时,就用到序列化与反序列化。将传输的对象序列化 传输到另一个系统中,另一个系统读取的时候通过将字节序列转换为对象读取出来.

serialVersionUID的作用

  • serialVersionUID的作用就是保证了序列化与反序列保证了 对象属性发生了改变不影响序列化与反序列的进行。比如讲
    将一个Customer对象实现了Serializable接口,如果不声明serialVersionUID属性,序列化该对象
    会默认生成一个serialVersionUID,然后向该对象中添加一个新的code属性,在将磁盘中的字节序列读取出来的时候,就会因为新的Customer对象中默认生成的serialVersionUID与磁盘中的字节序列serialVersionUID不一致而导致反序列胡失败。解决办法就是添加一个常量serialVersionUID,这样不由编译器生成serialVersionUID,那么serialVersionUID也就不会改变。那么不论对象怎么改,反序列化都没有问题.
    java.io.InvalidClassException: serialiable.Customer; local class incompatible: stream classdesc serialVersionUID = 2918975353393695766, local class serialVersionUID = -2999019177624378121在这里插入图片描述

正确序列化的方式
Person.java

package serialiable;

import java.io.Serializable;

public class Person implements  Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	public Person(int age, String name, String sex) {
		super();
		this.age = age;
		this.name = name;
		this.sex = sex;
	}
	private int  age;
	private  String  name;
	private  String sex;
	private String xx;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String toString() {
		return "Person [age=" + age + ", name=" + name + ", sex=" + sex + "]";
	}
	

}

CurrentDemo.java

package serialiable;

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

public class CurrentDemo {
	
	@SuppressWarnings("resource")
	public static void main(String[] args) {

		try {
			/**
			 *  1.通过ObjectOutputStream的成员方法writer将对象经过序列化存入到磁盘中
			 *  2.通过ObjectInputStream.readObject方法将字节序列 反序列化,读取对象信息
			 */
			/*Person person = new Person(22, "张三", "男");
			FileOutputStream fileOutputStream = new FileOutputStream(new File("C:\\Person.txt"));
			ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
			objectOutputStream.writeObject(person);
			System.out.println("对象序列化成功");
			
			FileInputStream fileInputStream = new FileInputStream(new File("C:\\Person.txt"));
			ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
			Person person2 = (Person) objectInputStream.readObject();
			System.out.println(person2);
			System.out.println("磁盘对象反序列化成功");*/
			
			
			/*
			 * 读取反序列化的对象
			 */
			FileInputStream fileInputStream = new FileInputStream(new File("C:\\Person.txt"));
			ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
			Person person2 = (Person) objectInputStream.readObject();
			System.out.println(person2);
			System.out.println("磁盘对象反序列化成功");
			
		} catch (FileNotFoundException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		} catch (ClassNotFoundException ex) {
			ex.printStackTrace();
		}

	}
}

在这里插入图片描述

没有声明serialVersionUID的错误例子
Customer.java

package serialiable;

import java.io.Serializable;

public class Customer implements  Serializable{
	
	public Customer(int age, String name, String sex) {
		super();
		this.age = age;
		this.name = name;
		this.sex = sex; 
	}
	private int  age;
	private  String  name;
	private  String sex;
	private String xx;
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public String toString() {
		return "Person [age=" + age + ", name=" + name + ", sex=" + sex + "]";
	}
	

}

FailureDemo.java

package serialiable;

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

public class FailureDemo {
	public static void main(String[] args) {

		try {
			/**
			 *  1.通过ObjectOutputStream的成员方法writer将对象经过序列化存入到磁盘中
			 *  2.通过ObjectInputStream.readObject方法将字节序列 反序列化,读取对象信息
			 */
			/*Customer customer = new Customer(22, "张三", "男");
			FileOutputStream fileOutputStream = new FileOutputStream(new File("C:\\Customer.txt"));
			ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
			objectOutputStream.writeObject(customer);
			System.out.println("对象序列化成功");
			
			FileInputStream fileInputStream = new FileInputStream(new File("C:\\Customer.txt"));
			ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
			Customer customer2 = (Customer) objectInputStream.readObject();
			System.out.println(customer2);
			System.out.println("磁盘对象反序列化成功");*/
			
			
			/*
			 * 读取反序列化的对象
			 */
			FileInputStream fileInputStream = new FileInputStream(new File("C:\\Customer.txt"));
			ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
			Customer customer2 = (Customer) objectInputStream.readObject();
			System.out.println(customer2);
			System.out.println("磁盘对象反序列化成功");
			
		} catch (FileNotFoundException ex) {
			ex.printStackTrace();
		} catch (IOException ex) {
			ex.printStackTrace();
		} catch (ClassNotFoundException ex) {
			ex.printStackTrace();
		}

	}
}

总结
序列化作为数据持久化的一个重要知识点,竟然到现在才了解。羞愧不已,与同行的人差距也越来越大,加油!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值