Java定制序列化内容

序列化给传递对象和报文带来了方便,如果没有序列化就没有系统间的交互,所以序列化非常重要。有些场景不需要把所有的属性都传递出去,所以需要针对实际情况定制化对象的序列化内容。针对定制化,Java提供了一接口Externalizable。

import java.io.Externalizable;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
import java.io.ObjectOutputStream;

public class Test {
	public static void main(String[] args) throws Exception {
		testPo po = new testPo(18, "小明");
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("F://testPo.txt"));
		out.writeObject(po);
		out.close();
		
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("F://testPo.txt"));
		testPo po2 = (testPo)in.readObject();
		System.out.println(po2.toString());
		in.close();
	}
}
class testPo implements Externalizable {
	private int i;
	private String str;
	
	public testPo(){
		System.out.println("testPo : 不带参数的构造方法");
	}		
	public testPo(int i, String str){
		this.i = i;
		this.str = str;
		System.out.println("testPo : 带参数的构造方法");
	}
	public String toString() {
		return str + "  " +i;
	}
	
	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		// TODO Auto-generated method stub
		System.out.println("testPo.writeExternal");
		out.writeObject(str);
		out.writeInt(i);
	}

	@Override
	public void readExternal(ObjectInput in) throws IOException,
			ClassNotFoundException {
		// TODO Auto-generated method stub
		System.out.println("testPo.readExternal");
		str = (String)in.readObject();
		i = in.readInt();
	}
}

输出结果:

Externalizable接口继承自Serialiazable接口,且有两个抽象方法,即实例中的writeExternal(arg)和readExternal(arg)看输出结果可以看出:

(1)、对象序列化时,会自动调用writeExternal(arg)方法,此方法用于定制序列化的内容,即对象的什么属性需要序列化,什么属性不需要序列化;针对不需要序列化的属性就没必要调用out.writeXX()方法;另外,还可以在该方法中自定义属性的内容。

(2)、对象反序列化时,会自动调用类中不带参数的构造函数,意思是会重新生成一个新的类对象(新对象的任何属性都没有值);这点与实现Serializable接口的类完全不同。

(3)、对象反序列化时,会自动调用readExternal(arg)方法,此方法用于给新生成的类对象赋值;这里可以在两个方法里把属性(int)不序列化(注释掉),你会发现结果反序列化结果中,属性(int)的值为0,即使开始构造对象时是赋值的。

所以,实现Externalizable接口的类,完全可以根据场景定制序列化内容。

 

当然,如果嫌这种方法麻烦,需要在方法里单独定制化内容,可以使用transient关键字。

transient是Java关键字之一,可以用来修饰属性,可以防止属性被序列化。

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


public class Test {
	public static void main(String[] args) throws Exception {
		testA A = new testA("hellow", "123456789");
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("F://testA.txt"));
		out.writeObject(A);
		out.close();
		
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("F://testA.txt"));
		testA A1 = (testA)in.readObject();
		System.out.println(A1.toString());
		in.close();
	}
}
class testA implements Serializable{

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String account;
	private transient String passWord;
	
	public testA(String account,String passWord){
		this.account = account;
		this.passWord = passWord;
	}
	public String toString() {
		return account + " " + passWord;
	}	
}

注意:由于Externalizable对象在默认情况下不保存它们的任何属性(不调用任何out.wirteXX()方法),所以transient关键字只能和Serializable对象一起使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值