1.需求
使用Externalizable实现序列化
2.Externalizable源码
public interface Externalizable extends java.io.Serializable {
/**
* The object implements the writeExternal method to save its contents
* by calling the methods of DataOutput for its primitive values or
* calling the writeObject method of ObjectOutput for objects, strings,
* and arrays.
*
* @serialData Overriding methods should use this tag to describe
* the data layout of this Externalizable object.
* List the sequence of element types and, if possible,
* relate the element to a public/protected field and/or
* method of this Externalizable class.
*
* @param out the stream to write the object to
* @exception IOException Includes any I/O exceptions that may occur
*/
void writeExternal(ObjectOutput out) throws IOException;
/**
* The object implements the readExternal method to restore its
* contents by calling the methods of DataInput for primitive
* types and readObject for objects, strings and arrays. The
* readExternal method must read the values in the same sequence
* and with the same types as were written by writeExternal.
*
* @param in the stream to read data from in order to restore the object
* @exception IOException if I/O errors occur
* @exception ClassNotFoundException If the class for an object being
* restored cannot be found.
*/
void readExternal(ObjectInput in) throws IOException, ClassNotFoundException;
}
首先,我们在序列化对象的时候,由于这个类实现了Externalizable 接口,在writeExternal()方法里定义了哪些属性可以序列化,
哪些不可以序列化,所以,对象在经过这里就把规定能被序列化的序列化保存文件,不能序列化的不处理,然后在反序列的时候自动调用readExternal()方法,根据序列顺序挨个读取进行反序列,并自动封装成对象返回,然后在测试类接收,就完成了反序列
所以说Exterinable的是Serializable的一个扩展
3.举个栗子
需要序列化的类Person
package com.serializable;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.text.SimpleDateFormat;
import java.util.Date;
public class Person implements Externalizable {
private static final long serialVersionUID = 2534579427612174172L;
private String name;
private Integer age;
private transient String gender;
public Person() {
}
public Person(String name, Integer age, String gender) {
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
Date date=new Date();
out.writeObject(name);
out.writeObject(age);
out.writeObject(date);
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
name=(String) in.readObject();
age=(Integer) in.readObject();
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
Date date=(Date)in.readObject();
System.out.println("反序列化后的日期为:"+sdf.format(date));
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", gender='" + gender + '\'' +
'}';
}
}
序列化类
public class Client {
/**
* 序列化方法
* @throws IOException
* @throws FileNotFoundException
*/
public void serializable(Person person) throws FileNotFoundException, IOException {
ObjectOutputStream outputStream=new ObjectOutputStream(new FileOutputStream("temp2"));
outputStream.writeObject(person);
}
/**
* 反序列化的方法
* @throws IOException
* @throws FileNotFoundException
* @throws ClassNotFoundException
*/
public Person deSerializable() throws FileNotFoundException, IOException, ClassNotFoundException{
ObjectInputStream ois=new ObjectInputStream(new FileInputStream("temp2"));
return (Person) ois.readObject();
}
@Test
public void test() throws Exception {
Client client=new Client();
Person person=new Person("村长",20,"man");
System.out.println("为序列化之前的相关数据如下:\n"+person.toString());
client.serializable(person);
Person newPerson=client.deSerializable();
System.out.println("-------------------------------------------------------");
System.out.println("序列化之后的相关数据如下:\n"+newPerson.toString());
}
}
4.注意
1.java中的序列化时transient变量(这个关键字的作用就是告知JAVA我不可以被序列化)和静态变量不会被序列化
2.也是最应该注意的,如果你先序列化对象A后序列化B,那么在反序列化的时候一定记着JAVA规定先读到的对象 是先被序列化的对象,不要先接收对象B,那样会报错.尤其在使用上面的Externalizable的时候一定要注意读取 的先后顺序
3.实现序列化接口的对象并不强制声明唯一的serialVersionUID,是否声明serialVersionUID对于对象序列化的向 上向下的兼容性有很大的影响
来源:oschina
链接:https://my.oschina.net/u/1398304/blog/1808675