`

有关Java序列化(三)——使用Externalizable

    博客分类:
  • Java
阅读更多

JDK中提供了另一个序列化接口--Externalizable,使用该接口之后,之前基于Serializable接口的序列化机制就将失效。Externalizable继承于Serializable,当使用该接口时,序列化的细节需要由程序员去完成。

测试代码:

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

public class Person implements Externalizable {

	private static final long serialVersionUID = -842029427676826563L;

	public static String name;
	private int age;
	private transient int workDay = 5;
	private String fClub;

	public Person() {
        System.out.println("none-arg constructor");
    }
	
	public Person(int age, String fClub) {
        this.age = age;
        this.fClub = fClub;
    }
	
	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getWorkDay() {
		return workDay;
	}

	public void setWorkDay(int workDay) {
		this.workDay = workDay;
	}

	public String getfClub() {
		return fClub;
	}

	public void setfClub(String fClub) {
		this.fClub = fClub;
	}

	private void writeObject(ObjectOutputStream out) throws IOException {
		out.defaultWriteObject();//执行默认的序列化机制
		out.writeInt(workDay);
		System.out.println("正在进行序列持久化");
	}

	private void readObject(ObjectInputStream in) throws IOException,
			ClassNotFoundException {
		in.defaultReadObject();
		workDay = in.readInt();
		System.out.println("读取持久化对象");
	}

	@Override
	public void readExternal(ObjectInput arg0) throws IOException,
			ClassNotFoundException {
		// TODO Auto-generated method stub
	}

	@Override
	public void writeExternal(ObjectOutput arg0) throws IOException {
		// TODO Auto-generated method stub	
	} 
}

 主测试类代码:

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

public class Hello {

	public static void main(String[] args) {
		Person person = new Person(26, "Juventus");
		person.setWorkDay(7);
		try {
			FileOutputStream fs = new FileOutputStream("foo.ser");
			ObjectOutputStream os = new ObjectOutputStream(fs);
			os.writeObject(person);
			os.close();

			Person.name = "Alex";

			FileInputStream in = new FileInputStream("foo.ser");
			ObjectInputStream s = new ObjectInputStream(in);
			Person p = (Person) s.readObject();
			System.out.println("name==" + Person.name + " age==" + p.getAge()
					+ " workDay==" + p.getWorkDay() + " fClub==" + p.getfClub());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

 程序输出为:

none-arg constructor
name==Alex age==0 workDay==5 fClub==null

 

       从结果来看,writeObject和readObject没再被执行,Person p = (Person) s.readObject()读取持久化类的时候调用了Person的无参构造函数。同时发现,foo.ser文件里只有类的类型声明,没有任何实例变量,Person对象中任何一个字段都没有被序列化,所以打印结果里面,age为0,fClub为null,而workDay为初始值5。

        如上所示的代码,由于writeExternal()与readExternal()方法未作任何处理,那么该序列化行为将不会保存/读取任何一个字段。

更改Person类:

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

public class Person implements Externalizable {

	private static final long serialVersionUID = -842029427676826563L;

	public static String name;
	private int age;
	private transient int workDay = 5;
	private String fClub;

	public Person() {
        System.out.println("none-arg constructor");
    }
	
	public Person(int age, String fClub) {
        this.age = age;
        this.fClub = fClub;
    }
	
	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getWorkDay() {
		return workDay;
	}

	public void setWorkDay(int workDay) {
		this.workDay = workDay;
	}

	public String getfClub() {
		return fClub;
	}

	public void setfClub(String fClub) {
		this.fClub = fClub;
	}

	/*//writeObject和readObject不再被执行
	private void writeObject(ObjectOutputStream out) throws IOException {
		out.defaultWriteObject();//执行默认的序列化机制
		out.writeInt(workDay);
		System.out.println("正在进行序列持久化");
	}

	private void readObject(ObjectInputStream in) throws IOException,
			ClassNotFoundException {
		in.defaultReadObject();
		workDay = in.readInt();
		System.out.println("读取持久化对象");
	}
	*/

	@Override
	public void writeExternal(ObjectOutput out) throws IOException {
		out.writeObject(fClub);
        out.writeInt(age);
        System.out.println("自定义序列化过程");
	} 
	
	@Override
	public void readExternal(ObjectInput in) throws IOException,
			ClassNotFoundException {
		fClub = (String) in.readObject();
        age = in.readInt();
        System.out.println("自定义反序列化");
	}
}

 主测试程序的输出结果为:

自定义序列化过程
none-arg constructor
自定义反序列化
name==Alex age==26 workDay==5 fClub==Juventus

        使用Externalizable进行序列化,当读取对象时,会调用被序列化类的无参构造器去创建一个新的对象,然后再将被保存对象的字段的值分别填充到新对象中。这就是为什么输出结果中会显示调动了无参构造器。由于这个原因,实现Externalizable接口的类必须要提供一个无参的构造器,且它的访问权限为public。

 

参考:

http://www.blogjava.net/jiangshachina/archive/2012/02/13/369898.html

分享到:
评论

相关推荐

    JAVA序列化Serializable及Externalizable区别详解

    主要介绍了JAVA序列化Serializable及Externalizable区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Java 串行化(序列化)Serializable/Externalizable

    NULL 博文链接:https://zhycaf.iteye.com/blog/982092

    Java高级程序设计实战教程第五章-Java序列化机制.pptx

    Java高级程序设计 第5章 Java序列化机制 5.1 应用场景 5.2 相关知识5.3 实施过程 5.4 拓展知识5.5 拓展训练 5.6 课后小结5.7 课后习题 5.8 上机实训 Java高级程序设计实战教程第五章-Java序列化机制全文共15页,当前...

    Java 对象序列化详解以及实例实现和源码下载

    Java中的序列化机制有两种实现方式: 一种是实现Serializable接口 另一种是实现Externalizable接口 区别: 实现Serializable接口 1 系统自动储存必要的信息 2 Java内建支持,易于实现,只需实现该接口即可,无须任何...

    深入探索Java对象的序列化

    Serializable有一个子接口Externalizable,实现Externalizable接口的类可以自行控制对象序列化荷反序列化过程。 一般来说,没有必要自己实现序列化接口,直接交给Java虚拟机是上策。 实现了序列化接口的类,如果...

    java序列化和反序列化,面试必备

    最近阅读Serializable接口和Externalizable接口的源码,并结合了一些资料,对面试过程中与序列化相关的内容做了一些总结。 一、序列化、反序列化、使用场景、意义。 序列化:将对象写入IO流中; 反序列化:从IO流中...

    Java中的序列化与反序列化.pdf

    Serializable接口和Externalizable接口实现序列化和反序列化

    xml的序列化与验证

    1、xml序列化的Java3种实现方法 1)Serializable和Externalizable接口Xstream框架2)Simple框架 3)Apache的AXIOM框架 2、XML验证文档的生成工具 trang.jar 3、利用XSD文件的XML3种验证方法 1)Dom4j的SAXValidator ...

    JDK_API_1_6

    Externalizable Externalizable 实例类的唯一特性是可以被写入序列化流中,该类负责保存和恢复实例内容。 FileFilter 用于抽象路径名的过滤器。 FilenameFilter 实现此接口的类实例可用于过滤器文件名。 ...

    groovy-io:与JSON格式之间完美的Groovy序列化。 此外,还支持JSON的精美打印(与jsonEditorOnline样式匹配)

    groovy-io消除了使用ObjectInputStream / ObjectOutputStream序列化对象的需要,而使用了JSON格式。 有第三个可选类( JsonObject ),请参见下面的“非类型化用法”。 groovy-io不需要类实现Serializable或...

    dom4J的使用方法ppt.

    dom4J的使用方法ppt.

    VALJOGen:VALue Java 对象生成器 (VALJOGen)

    VALJOGen 可用于从带注释的 Java 接口生成现代 Java 7/8+ 值类。 特征: 可以从您的接口使用自动实现的 getter 和 setter生成值对象。 支持自动实现工厂方法、构造函数、对象。 哈希码,对象。 等于,对象。 ...

    j2ee中英文对照版api

    这类命令可以使用 Externalizable 接口或特定于应用程序的方法来获取数据。 英文文档: JavaBeans components that are Activation Framework aware implement this interface to find out which command verb ...

    LargeCollections

    这允许您的集合增长得非常大,因为它不使用 JVM 堆内存。 应该浏览此项目的以获取更多信息。 #关键设计原则# 底层 java.util.Map(java.util.List 和 java.util.Set) 实现由支持。 LevelDB 是一个由 Google 编写的...

    cocoaAMF使用指南.zip

    You can encode keyed and non-keyed, where the latter means you're encoding an externalizable class. While deserializing, if no class with the classname of the received object is found, CocoaAMF ...

Global site tag (gtag.js) - Google Analytics