java序列化

java序列化

序列化(也可叫做持久化)是指将对象的状态信息转化为可以存储或者传输的形式的过程,序列化后的信息可以暂时的放在存储区或者写入文件中。

反序列化是指将文件或存储区的信息转换为对象的形式。

什么情况需要需序列化?

  • 当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
  • 当你想用套接字在网络上传送对象的时候;
  • 当你想通过RMI传输对象的时候; 

如何进行序列化和反序列化 ? 

建立一个Emploee类实现java.io.Serializable接口。对于一个实体类,不想将所有的属性都进行序列化,有专门的关键字 transient 注明该属性是短暂的。

public class Employee implements Serializable {

	/**
	 * 序列化版本号
	 */
	private static final long serialVersionUID = 2540986455050446094L;
	public String name;
	public String address;
	public transient int SSN;
	public int number;
}

写一个测试类将对象存储在D://serializable.ser中。

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

public class SerializableTest {
	

	public SerializableTest() {

	}

	public static void main(String[] args) {
		Employee employee = new Employee();
		employee.name = "Reyan Ali";
		employee.address = "Phokka Kuan, Ambehta Peer";
		employee.SSN = 112233;
		employee.number = 101;
		
		
		try {
			File file = new File("D://employee.ser");
			FileOutputStream outputStream = 
					new FileOutputStream(file);
			ObjectOutputStream objectOutputStream = 
					new ObjectOutputStream(outputStream);
			
			objectOutputStream.writeObject(employee);
			
			objectOutputStream.close();
			outputStream.close();
			
			System.out.printf("Serialized data is saved in D://employee.ser");
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}

打开D盘(我存储在了D盘), 

 

文件存在与D://employee.ser。

返序列化。

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;

public class DeSerrializable {

	public static void main(String[] args) {
		
		Employee employee = null;
		
		try {
			File file = new File("D://employee.ser");
			FileInputStream inputStream = 
					new FileInputStream(file);
			ObjectInputStream objectInputStream = 
					new ObjectInputStream(inputStream);
			employee = (Employee) objectInputStream.readObject();
			System.out.println("deserializable....");
			System.out.println("name: "+employee.name);
			System.out.println("address: "+employee.address);
			System.out.println("number: "+employee.number);
			System.out.println("SSN: "+employee.SSN);
			inputStream.close();
			objectInputStream.close();
		}catch (Exception e) {
			e.printStackTrace();
		}

	}

}

输出结果为

deserializable....
name: Reyan Ali
address: Phokka Kuan, Ambehta Peer
number: 101
SSN: 0

结果也可以看出SSN属性由于使用了关键字transient并没有被序列化。

serialVersionUID的作用

serialVersionUID 简单来说就是这个类序列化的版本号,他在序列化和反序列化起到验证版本是否一致的作用,序列化时会将serialVersionUID 一并序列化到文件中,当反序列化时会将serialVersionUID 传送过来,系统会检测到serialVersionUID ,并将其与lei中的serialVersionUID 进行比较,如果是相同,就可以反序列化成功,不同则报异常。

java.io.InvalidClassException: com.xxxxxx;   local class incompatible: stream classdesc serialVersionUID = 5590259895198052390, local class serialVersionUID = 7673969121092229700  

serialVersionUID 版本号可以有两种方式生成

显式生成 :就是在类中以成员属性的形式定义。

例如:

//这种显式生成默认的serialVersionUID  默认都是1L 
//这种方式生成的serialVersionUID 不唯一 
private static final long serialVersionUID = 1L;
// 这种也是系统生成的 
//但是是根据包名,类名,继承关系,非私有的方法和属性,以及参数,返回值等诸多因子计算得出的
//极度复杂生成的一个64位的哈希字段。基本上计算出来的这个值基本上是唯一的.
private static final long serialVersionUID = 2540986455050446094L;

隐式生成:在类的编译时生成,也是根据包名,类名,继承关系,非私有的方法和属性,以及参数,返回值等诸多因子计算得出的极度复杂生成的一个64位的哈希字段。但是这种serialVersionUID 并不是永久不变的,当类中的继承关系或者属性等发生改变时,重新编译会重新生成一个serialVersionUID,以前序列化的对象在反序列化时就会出现serialVersionUID不同的情况,导致反序列化不成功,报java.io.InvalidClassException异常。

所以在要序列化的对象所属的类,应显式去添加一个serialVersionUID。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值