- 语法
class ClassName implements Externalizable {
// other code
}
例子
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
public class Student implements Externalizable {
private static final long serialVersionUID = 1l;
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeUTF(name);
out.writeInt(age);
}
@Override
public void readExternal(ObjectInput in)
throws IOException, ClassNotFoundException {
this.name = in.readUTF();
this.age = in.readInt();
}
}
import java.io.*;
public class ExternalizableTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Student student = new Student();
student.setAge(27);
student.setName("Tom");
try (ObjectOutputStream outputFile = new ObjectOutputStream(new FileOutputStream(new File("./Student.txt")))) {
outputFile.writeObject(student); // write person to file
}
// deserializable
// read file
Student studentDeserializable;
try (ObjectInputStream inputFile = new ObjectInputStream(new FileInputStream(new File("./Student.txt")))) {
studentDeserializable = (Student) inputFile.readObject();
}
System.out.println(studentDeserializable.getName());
}
}
输出结果:
- Externalizable和Serializable的区别
1、序列化责任
这里的关键区别是我们如何处理序列化过程。当类实现java.io.Serializable接口时,JVM完全负责序列化类实例。在Externalizable的情况下,程序员应该负责整个序列化和反序列化过程。
2、用例
如果我们需要序列化整个对象,那么Serializable接口更适合。另一方面,对于自定义序列化,我们可以使用Externalizable控制流程。
3、性能
java.io.Serializable接口使用反射和元数据,这会导致相对较慢的性能。相比之下,Externalizable接口使您可以完全控制序列化过程。
4、阅读顺序
使用Externalizable时,必须按照写入时的确切顺序读取所有字段状态。否则,我们会得到一个例外。
例如,如果我们更改Student类中的代码和name属性的读取顺序,则将抛出java.io.EOFException。同时,Serializable接口没有这个要求。
5、自定义序列化
我们可以通过使用transient关键字标记字段来使用Serializable接口实现自定义序列化。 JVM不会序列化特定字段,但它会将字段添加到具有默认值的文件存储。这就是为什么在自定义序列化的情况下使用Externalizable是一个好习惯。