序列化控制

实现Externalizable

重写writeExtrenal()和readExternal()方法。这两个方法在序列化和反序列化的时候会自动调用。

package com.zachary.io.serializable;

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;

class Blip1 implements Externalizable {
	public Blip1(){
		System.out.println("Blip1 Constructor");
	}
	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		System.out.println("Blip1.writeExternal");
	}
	@Override
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		System.out.println("Blip1.readExternal");
	}
}

class Blip2 implements Externalizable {
	Blip2(){
		System.out.println("Blip2 constructor");
	}
	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		System.out.println("Blip2.writeExternal");
	}
	@Override
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		System.out.println("Blip2.readExternal");
	}
}

/**
 * @author Zachary.Zheng
 * @version 1.0
 * @date 2020年6月3日 下午1:13:43
 */
public class Blips{
	public static void main(String[] args) throws Exception {
		Blip1 blip1 = new Blip1();
		Blip2 blip2 = new Blip2();
		
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("file/output/serializable/Blips.out"));
		out.writeObject(blip1);
		out.writeObject(blip2);
		out.flush();
		out.close();
		
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("file/output/serializable/Blips.out"));
		in.readObject();
//		in.readObject(); // 构造函数不是public的会报:java.io.InvalidClassException: com.zachary.io.serializable.Blip2; no valid constructor
		in.close();
	}
}

Output:
Blip1 Constructor
Blip2 constructor
Blip1.writeExternal
Blip2.writeExternal
Blip1 Constructor
Blip1.readExternal

恢复b1后,会调用Blip1的默认构造器。对于Serializable对象完全由它存储的字节序列化数据来构造,Externalizable对象需要调用构造器方法。

Externalizable序列化部分字段

package com.zachary.io.serializable;

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;

/**
 * @author Zachary.Zheng
 * @version 1.0
 * @date 2020年6月3日 下午1:35:49
 */
public class Blip3 implements Externalizable{
	private int i;
	private String s; // No initialzation
	public Blip3() {
		System.out.println("Blip3 constructor");
	}
	public Blip3(int i, String s) {
		System.out.println("Blip3(int i, String s) constructor");
		this.i = i;
		this.s = s;
	}
	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeInt(i);
		out.writeObject(s);
	}
	@Override
	public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
		i = in.readInt();
		s = (String) in.readObject();
	}
	
	public String toString() {
		return s + i;
	}
	
	public static void main(String[] args) throws Exception {
		Blip3 b3 = new Blip3(47, "A String ");
		System.out.println(b3);
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("file/output/serializable/Blip3.out"));
		out.writeObject(b3);
		out.flush();
		out.close();
		
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("file/output/serializable/Blip3.out"));
		b3 = (Blip3) in.readObject();
		System.out.println(b3);
		in.close();
	}
}

Output:
Blip3(int i, String s) constructor
A String 47
Blip3 constructor
A String 47

transient(瞬时)关键字

不想被序列化的敏感数据,使用关键字transient修饰后值不会被序列化。

package com.zachary.io.serializable;

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

/**
 * @author Zachary.Zheng
 * @version 1.0
 * @date 2020年6月3日 下午1:59:18
 */
public class Logon implements Serializable {
	private static final long serialVersionUID = 1L;
	private Date date = new Date();
	private String name;
	private transient String password;
	
	public Logon(String name, String password) {
		super();
		this.name = name;
		this.password = password;
	}
	@Override
	public String toString() {
		return "Logon [date=" + date + ", name=" + name + ", password=" + password + "]";
	}
	
	public static void main(String[] args) throws Exception {
		Logon a = new Logon("Hulk", "myLittlePony");
		System.out.println("Logon a = " + a);
		ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("file/output/serializable/Logon.out"));
		out.writeObject(a);
		out.close();
		
		ObjectInputStream in = new ObjectInputStream(new FileInputStream("file/output/serializable/Logon.out"));
		a = (Logon) in.readObject();
		System.out.println("Logon a = " + a);
		in.close();
	}
}

Output:
Logon a = Logon [date=Wed Jun 03 16:38:25 CST 2020, name=Hulk, password=myLittlePony]
Logon a = Logon [date=Wed Jun 03 16:38:25 CST 2020, name=Hulk, password=null]

Externalizable的替代方法

实现Serializable接口,添加writeObject()和readObject()方法。在序列化和反序列化时会自动分别调用这两个方法。

  • defaultWriteObject()和defaultReadObject()方法会执行默认的序列化。
  • transient部分使用writeObject()和readObject()序列化。
package com.zachary.io.serializable;

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

/**
 * @author Zachary.Zheng
 * @version 1.0
 * @date 2020年6月3日 下午2:21:05
 */
public class SerialCtl implements Serializable {
	private static final long serialVersionUID = 1L;
	private String a;
	private transient String b;
	
	public SerialCtl(String a, String b) {
		super();
		this.a = "No transient" + a;
		this.b = "Transient" + b;
	}
	
	@Override
	public String toString() {
		return "SerialCtl [a=" + a + ", b=" + b + "]";
	}

	private void writeObject(ObjectOutputStream stream) throws IOException {
		stream.defaultWriteObject();
		stream.writeObject(b);
	}
	private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
		stream.defaultReadObject();
		b = (String) stream.readObject();
	}
	
	public static void main(String[] args) throws Exception {
		SerialCtl sc = new SerialCtl("Test1", "Test2");
		System.out.println("Before\n" + sc);
		
		ByteArrayOutputStream buf = new ByteArrayOutputStream();
		ObjectOutputStream out = new ObjectOutputStream(buf);
		out.writeObject(sc);
		out.close();
		
		ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(buf.toByteArray()));
		sc = (SerialCtl) in.readObject();
		System.out.println("After\n" + sc);
		in.close();
	}
}

Output:
Before
SerialCtl [a=No transientTest1, b=TransientTest2]
After
SerialCtl [a=No transientTest1, b=TransientTest2]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值