一. 自动序列化
1. java中要序列化对象要时,只要实现Serilizable接口即可,默认对象的所有属性都会被序列化,但是静态变量(static)不能被序列化。
实例代码如下:
1 public class Student implementsSerializable {2
3 private static final long serialVersionUID = -2378603120577464262L;4
5 public Student(intid, String name, LocalDate birth) {6 this.id =id;7 this.name =name;8 this.birth =birth;9 }10
11 private intid;12 privateString name;13 privateLocalDate birth;14
15 public intgetId() {16 returnid;17 }18
19 public void setId(intid) {20 this.id =id;21 }22
23 publicString getName() {24 returnname;25 }26
27 public voidsetName(String name) {28 this.name =name;29 }30
31 publicLocalDate getBirth() {32 returnbirth;33 }34
35 public voidsetBirth(LocalDate birth) {36 this.birth =birth;37 }38
39 @Override40 publicString toString() {41 return "id=" + this.id + ";name=" + this.name + ";birth=" + this.birth;42 }43 }
序列化代码实现如下:
1 public classTestClass {2
3 public static void main(String[] args) throwsIOException {4 try{5 serialize();6 } catch(Exception e) {7 System.err.println(e);8 }9
10 try{11 deserialize();12 } catch(Exception e) {13 System.err.println(e);14 }15 }16
17 private final static String FILENAME = "D:\\workfolder\\abc.txt";18
19 public static void serialize() throwsIOException {21 Student student = new Student(10, "张三", LocalDate.of(2005, 10, 10));22 System.out.println(student);23 ObjectOutputStream os = new ObjectOutputStream(newFileOutputStream(FILENAME));24 os.writeObject(student);25 os.flush();26 os.close();27 }28
29 public static void deserialize() throwsIOException, ClassNotFoundException {30 ObjectInputStream stream = new ObjectInputStream(newFileInputStream(FILENAME));31 Student student =(Student) stream.readObject();32 stream.close();33 System.out.println(student);35 }36
37 }
结果显示:
id=10;name=张三;birth=2005-10-10
id=10;name=张三;birth=2005-10-10
有时候对象的某些属性不需要进行序列化,比方密码等敏感数据,可以在这些变量上加上 transient关键字来修饰,用transient来修饰的属性则不会被序列化。
比如,将Student的birth属性改为如下:
private transient LocalDate birth;
重新执行序列化和反序列化,则如下结果:
id=10;name=张三;birth=2005-10-10
id=10;name=张三;birth=null
2.transient关键字只能修饰变量,而不能修饰方法和类。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
二. 自定以序列化
1: JDK中提供了另一个序列化接口--Externalizable,使用该接口之后,之前基于Serializable接口的序列化机制就将失效。Externalizable继承于Serializable,当使用该接口时,序列化的细节需要由程序员去完成。
实例代码如下:
1 public classTestClass {2
3 public static voidmain(String[] args) {4 try{5 serialize();6 } catch(Exception e) {7 System.err.println(e);8 }9
10 try{11 deserialize();12 } catch(Exception e) {13 System.err.println(e);14 }15 }16
17 private final static String FILENAME = "D:\\workfolder\\abc.txt";18
19 public static void serialize() throwsIOException {20 Address address = new Address("广东省", "广州市", "天河区");21 ObjectOutputStream os = new ObjectOutputStream(newFileOutputStream(FILENAME));22 os.writeObject(address);23 os.flush();24 os.close();25 }26
27 public static void deserialize() throwsIOException, ClassNotFoundException {28 ObjectInputStream stream = new ObjectInputStream(newFileInputStream(FILENAME));29 Address address =(Address) stream.readObject();30 stream.close();31 System.out.println(address);32 }33 }
1 public class Address implementsExternalizable {2
3 privateString sheng;4 privateString shi;5 privateString qu;6
7 publicAddress() {
System.out.println("init...");8 }9
10 publicAddress(String sheng, String shi, String qu) {11 super();12 this.sheng =sheng;13 this.shi =shi;14 this.qu =qu;15 }16
17 publicString getSheng() {18 returnsheng;19 }20
21 public voidsetSheng(String sheng) {22 this.sheng =sheng;23 }24
25 publicString getShi() {26 returnshi;27 }28
29 public voidsetShi(String shi) {30 this.shi =shi;31 }32
33 publicString getQu() {34 returnqu;35 }36
37 public voidsetQu(String qu) {38 this.qu =qu;39 }40
41 @Override42 publicString toString() {43 return "sheng=" + this.sheng + ";shi=" + this.shi + ";qu=" + this.qu;44 }45
46 @Override47 public void writeExternal(ObjectOutput out) throwsIOException {48
49 out.writeUTF(sheng);50 out.writeUTF(shi);51 out.writeUTF(qu);52 }53
54 @Override55 public void readExternal(ObjectInput in) throwsIOException, ClassNotFoundException {56 sheng =in.readUTF();57 shi =in.readUTF();58 qu =in.readUTF();59 }60 }
输出结果如下:
init...
sheng=广东省;shi=广州市;qu=天河区
使用Externalizable进行序列化,对象必须有一个无参的构造函数,且访问权限为public,当读取对象时,会调用被序列化类的无参构造器去创建一个新的对象,然后再将被保存对象的字段的值分别填充到新对象中。
2: 实现Serializable , 添加下列两个方法,
private void writeObject(java.io.ObjectOutputStream s) throws IOException {
...
}
private void readObject(java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
...
}
具体实现略