java中序列化和反序列化

Serializable(序列化)是java中的一个接口,通过让类实现这个接口,可以保存对象的状态。序列化有以下几个知识点:

1. 序列化只会保存对象的变量信息,不会保存对象的方法信息

2. 如果父类实现了Serializable接口,则子类默认实现了Serializable接口,即使子类没有声明也一样。

3. 当对象被序列化时,如果对象包含了对其他对象的引用,则其他对象也会被序列化。比如说一个类A里面有一个变量 b 是引用B类的一个对象,则当A类的对象a被序列化时,b对象也会被序列化。

4. 当对象被序列化时,如果对象中有成员变量不能被序列化,则会抛出异常

5. 静态变量不会被序列化,因为静态变量属于类而不属于对象。

6. 有transient标记的变量不会被序列化

有了序列化之后就会有反序列化。反序列化是将序列化保存的对象的状态还原出来。其有以下几个知识点:

1. 反序列化不会调用对象的构造函数

2. 反序列化是在堆中新建对象并尝试还原保存的对象的状态,而不是对原有对象的操作

3. 当原有对象中有transient标识的不序列化变量时,反序列化时会使用其默认值。主数据类型(int , long , double, boolean, char ···)会被赋值为默认值(int 为0, boolean 为 false),而引用对象则会被赋值为null。

4. 当原有对象中有静态变量时,反序列化时其值等于最近对该变量操作所得的值。比如说程序初始化该静态变量为1,在反序列化之前又对该静态变量赋值为100,那么反序列化之后该静态变量的值就是100而不是1.

下面通过一个简单的小程序来说明静态变量和transient不会被序列化

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

class A implements Serializable
{
	public static int staticInt = 3; // 静态变量不会被序列化
	private String string;
	private transient int num = 1;  // 这个变量不会被序列化
	
	A(String s, int num)
	{
		string = s;
		this.num = num;
	}
	
	public int getNum()
	{
		return num;
	}

	public void setNum(int num)
	{
		this.num = num;
	}

	public String getString()
	{
		return string;
	}
	public void setString(String string)
	{
		this.string = string;
	}
	
}

public class Test
{
	public static void printA(A a, String name)
	{
		System.out.println("----------" + name + "-------------");
		System.out.println("string: " + a.getString());
		System.out.println("num: " + a.getNum());
		System.out.println("staticInt: " + a.staticInt);
	}
	
	public static void main(String[] argv)
	{
		// 创建两个A对象
		A a = new A("hello", 10);
		A aa = new A("world", 20);
		
		// 输出其内容
		System.out.println("-------------before Serializable--------------");
		printA(a, "a");
		printA(aa, "aa");
		
		// 对两个A对象进行序列化
		try
		{
			ObjectOutputStream ous = new ObjectOutputStream(new FileOutputStream("a.txt"));
			ous.writeObject(a);
			ous.writeObject(aa);
			ous.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		
		// 序列化后改变对象 a 和 aa 的值,并输出
		a.setString("hello world!");
		a.setNum(30);
		aa.setString("world hello");
		aa.setNum(40);
		A.staticInt = 100;
		System.out.println("-------------after Serializable, change a and aa--------------");
		printA(a, "a");
		printA(aa, "aa");
		
		// 反序列化并输出结果
		try
		{
			ObjectInputStream ois = new ObjectInputStream(new FileInputStream("a.txt"));
			A aNew = (A) ois.readObject();
			A aaNew = (A) ois.readObject();
			
			System.out.println("--------------deserializable--------------");
			printA(a, "a");
			printA(aa, "aa");
			printA(aNew, "aNew");
			printA(aaNew, "aaNew");
			
			ois.close();
		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		catch (ClassNotFoundException e)
		{
			e.printStackTrace();
		}
	}
}

程序运行结果如下


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值