Java序列化与反序列化

在Java中,序列化其实有两个用处,保存和传送数据。

保存数据:将对象的状态持久保存在存储媒体(数据库或文件系统)上,以后可以重新创建精确的副本。

Java允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM处于运行时,这些对象才可能存在,也就是说,如果JVM停止了,原本占用的内存被释放,对象自然也不复存在。如果要求在JVM停止运行之后能够保存指定的对象,并在将来重新读取被保存的对象,Java对象序列化就能够实现。使用Java对象序列化,在保存对象时,会把其状态保存为一组字节,以后如果要用到这个对象,就可以通过反序列化,将这些字节组装成对象。注意,对象序列化保存的是对象的"状态",即它的成员变量,而静态变量属于类的状态,由此可知,对象序列化不会关注类中的静态变量。

传送数据:将对象从一个应用程序域发送到另一个应用程序域中(远程调用RMI)。

当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为对象,而不是通过构造方法新建一个新的对象再赋予原来的值。将对象转化为流的过程其实就是序列化(Serialization),而将流重新转化成对象的过程则是反序列化(Deserialization)。


下面是序列化对象信息:

public class Person implements Serializable
{
	private static final long	serialVersionUID	= 1L;
	private int		age;
	private String	name;

	public Person(String name, int age)
	{
		this.age = age;
		this.name = name;
	}

	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;
	}

	@Override
	public String toString()
	{
		return "Person [ name = " + name + ", age = " + age + " ]";
	}
}

上面代码有: private static final long serialVersionUID = 1L;
这个序列化ID的作用是用来决定是否可以反序列化。如果有两个类,都实现了Serializable,且功能代码完全一致,一个负责序列化,另一个负责反序列化,如果两者的序列化ID不同,那么不能相互序列化和反序列化。

通过write()方法把对象信息保存在文件;通过read方法把对象从文件提取出来,而不用通过构造方法生成。

public class Test
{

	public static void main(String[] args)
	{
		write();
		read();
	}

	private static void write()
	{
		Person student = new Person("shawn", 18);

		try
		{
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("seria.txt"));
			out.writeObject(student); //
			System.out.println("Object has been written.");
			out.close();
		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	private static void read()
	{
		try
		{
			ObjectInputStream in = new ObjectInputStream(new FileInputStream("seria.txt"));
			Person studentRead = (Person) in.readObject();
			System.out.println("Object is:");
			System.out.println(studentRead);
			in.close();
		} catch (FileNotFoundException e)
		{
			e.printStackTrace();
		} catch (IOException e)
		{
			e.printStackTrace();
		} catch (ClassNotFoundException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
默认情况下,是调用 ObjectOutputStream 的 defaultWriteObject 方法以及 ObjectInputStream 的 defaultReadObject 方法进行序列化和反序列化。但是,序列化文件不安全,所有程序都可以访问。所以如果传送的序列化对象数据比较敏感,则最好不用这个方式,而采用 writeObject 和 readObject 方法,进行用户自定义的序列化和反序列化。自定义的 writeObject 和 readObject 方法可以允许用户控制序列化的过程,比如可以在序列化的过程中动态改变序列化的数值。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值