java对象序列化(二)

自定义序列化

递归序列化:当对某个对象序列化时,会自动序列化该对象的实例变量,某个实例对象引用到另一个对象,则被引用的对象也会被序列化。

在实例变量前加transient关键字修饰,可以指定该对象实例化时无需理会这个实例变量。
public class Student implements Serializable{
	private String name;
	private transient int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	
}
	public static void main(String[] args) throws IOException, ClassNotFoundException {
		try (FileOutputStream outputStream = new FileOutputStream("e://student");
				FileInputStream inputStream = new FileInputStream("e://student");
				ObjectOutputStream oos = new ObjectOutputStream(outputStream);
				ObjectInputStream ois = new ObjectInputStream(inputStream);) {
		
			Student s = new Student("aaa", 12);
			oos.writeObject(s);
			Student s2 = (Student) ois.readObject();
			System.out.println(s2);		//输出name=aaa,age=0
		}
	}


实现自定义序列化:

private void writeObject(java.io.ObjectOutPutStream out)throws IOException

private void readObject(java.io.ObjectInPutStream in)throws IOException,ClassNotFoundException

重写writeObject()方法,获得对序列化机制的控制,控制那些实例变量被序列化,怎样序列化,通过readObject()反序列化对象。

public class Student implements Serializable{
	private String name;
	private int age;
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	private void writeObject(ObjectOutputStream out) throws IOException{
		out.writeObject(new StringBuilder(name).reverse());
		out.writeInt(age+1);
	}
	
	private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException{
		this.name = ((StringBuilder)in.readObject()).reverse().toString();
		this.age = in.readInt()-1;
	}
	
	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	
}

writeReplace()方法将序列化的对象替换为该方法返回的对象
private Object writeReplace() throws ObjectStreamException{
		return new Student("tom", 5);
	}
在Student类中覆盖writeReplace() ,则该对象序列化的对象时该方法的返回值
反序列化该对象得到的对象是:Student [name=tom, age=5]
与writeReplace方法对应的是readResolve方法

readResolve会替代原来的反序列化的对象,readObject得到的对象将会被丢弃.
private Object readResolve(){
		return name;
	}
反序列化对象将会得到,name属性的值


实现Externalizable接口的序列化:

public class Test2 implements Externalizable{
	private int i;
	private String str;
	
	public Test2(int i, String str) {
		this.i = i;
		this.str = str;
	}
	
	public Test2() {
	}


	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		// TODO Auto-generated method stub
		out.writeObject(str);
		out.writeInt(i);
	}

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

	
}
覆盖
writeExternal 
readExternal

方法来自己决定需要序列化或反序列化哪些实例变量。当使用
Externalizable
来反序列化对象时,会先调用带对象的无参构造器,所以必须提供public无参的构造器。


对象序列化的注意事项:

1.对象的类名,实例变量都会被序列化;方法、类变量、transient修饰的变量都不会被序列化
2.保证序列对象的实例变量都是可序列化的,要不然该类不可序列化
3.反序列化必须要有对象的class文件
4.读取对象的二进制文件时,必须按照序列化的顺序来反序列化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值