Serialize的使用

1. 什么是序列化:

    a) 把对象转换为字节序列的过程叫序列化对象。

    b) 把字节序列恢复为对象的过程叫反序列化。

2.用途:【序列化之后就可以存储在内存中或在网络中传输】

3、序列化的实现方式:2种

    a) 实现 Serializable 接口:java.io.ObjectOutputStream表示对象输出流,writeObject(obj)把指定对象序列化把得到的字节序列写到目标输出流;序列化的时候的一个关键字:transient(临时的)。它声明的变量实行序列化操作的时候不会写入到序列化文件中去。

    b) 实现 Externalizable 接口(很少使用):java.io.ObjectInputStream表示对象输出流,readObject(obj)将其反序列化并得到对象; 一个类中我们只希望序列化一部分数据,其他数据都使用transient修饰的话显得有点麻烦,这时候我们使用externalizable接口,指定序列化的属性。

4. Java中常见的序列化: 包括Java原生以流的方法进行的序列化、Json序列化、FastJson序列化、Protobuff序列化。

https://blog.csdn.net/pistolove/article/details/60321123

5. 解释SerialVersionUID的两种方式:

    a) default: 1L

    b) 根据报名类名方法名变量名来产生一个64bit的hash字段。

  作用:如果不写SerialVersionUID的话,java编译器会进行摘要,有一丝的变化摘要都是不同,安全机制都会拒绝加载,而如果显示写出只要UID相同就不会拒绝加载。

6.注意:

    a) 父类实现序列化,子类自动序列化,无需显示实现。

    b) 当一个对象的实例变量引用其他对象时,序列化该对象也要序列化引用对象。

    c) 并不是所有的对象都是可以序列化的。

    d) 尽量不要使用,可能存在 bug 和 security 问题;增加了 Test 的压力。

    e) 要被继承的类和接口尽量不要序列化。

    f) 即使要是有序列化,也要尽量使用自定义序列化(自定义readObject和writeObject)。

Example:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Date;

public class Period implements Serializable {
	
	
    private final Date start;
    private final Date end;
    
    public Period(Date start, Date end) {
    	this.start = new Date(start.getTime());
    	this.end = new Date(end.getTime());
    	
    	if (this.start.compareTo(this.end) > 0)
    	{
    		throw new IllegalArgumentException(
    				this.start + " is after " + this.end);
    	}
    }
    
	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
		in.defaultReadObject();
		
		// Check that our invariants are satisfied
    	if (this.start.compareTo(this.end) > 0)
    	{
    		throw new IllegalArgumentException(
    				this.start + " is after " + this.end);
    	}
	}
    
    public Date start() {
    	return start;
    }

    
    public Date end() {
    	return end;
    }
    
    public static void main(String[] args) {
    	Date date1 = new Date(1225481126447L);
    	Date date2 = new Date(1403441275025L);
    	
    	Period period = new Period(date1, date2);
    	System.out.println(period.start());
    	
    	date1.setTime(1325481126447L);
    	System.out.println(period.start());
    }
}

Example2:

package serialization;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;

public class SerializeTest implements Serializable {
	private static final long serialVersionUID = -7066215824837902304L;

	private String message = null;
	private int number = 0;
	
	private Object writeReplace() throws ObjectStreamException {
		System.out.println("writeReplace invoked");
		return this;
	}
	
	private void writeObject(ObjectOutputStream out) throws IOException {
		System.out.println("writeObject invoked");
		out.writeObject(this.message == null ? "------" : this.message);
	}
	
	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
		System.out.println("readObject invoked");
		this.message = (String) in.readObject();
		System.out.println("get message:" + this.message);
	}
	
	private Object readResolve() throws ObjectStreamException {
		System.out.println("readResolve invoked");
		return this;
	}
	
	public Object serialize() throws IOException, ClassNotFoundException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		ObjectOutputStream oos = new ObjectOutputStream(baos);
		oos.writeObject(this);
		ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
		ObjectInputStream ois = new ObjectInputStream(bais);
		return ois.readObject();		
	}
	
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		SerializeTest foo = new SerializeTest();
		foo.serialize();
	}
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值