失效链接处理 |
java对象默认序列化的干预方法 PDF 下载
本站整理下载:
相关截图:
主要内容:
1.1:将某个成员变量字段加transient(可跳过的),序列化的时候该字段信息就为空比如
1.public class Person implements Serializable {
2. ...
1. private String name = null;
2.
3. transient private Integer age = null; //另外Integer类型的成员变量也是序列化时不考虑的信息
4. //也就是敏感字段
3. private Gender gender = null; ...
4.}
5. public Person(String name, Integer age, Gender gender) {
6. System.out.println("arg constructor");
7. this.name = name;
8. this.age = age;
9. this.gender = gender;
10. }
5.}
6. Person person = new Person("John", 101, Gender.MALE); //创建的对象
再执行SimpleSerial应用程序(这是程序源文件的别称),会有如下输出:
1.arg constructor
2.[John, null, MALE]
2.
其它干预默认序列化的方法如下有时间再看,或者碰到了序列化问题再来看看: https://blog.csdn.net/femalcoder/article/details/77650680?biz_id=102&utm_term=%20Java%20%E6%A0%87%E5%87%86%E7%B1%BB%E6%98%AF%E5%90%A6%E6%98%AF%E5%8F%AF%E5%BA%8F%E5%88%97%E5%8C%96&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-77650680&spm=1018.2118.3001.4187
该链接的原文链接:http://www.blogjava.net/jiangshachina/archive/2012/02/13/369898.html
.2 writeObject()方法与readObject()方法
对于上述已被声明为transitive的字段age,除了将transitive关键字去掉之外,是否还有其它方法能使它再次可被序列化?方法之一就是在Person类中添加两个方法:writeObject()与readObject(),如下所示:
1.public class Person implements Serializable {
2. ...
3. transient private Integer age = null;
4. ...
5.
6. private void writeObject(ObjectOutputStream out) throws IOException {
7. out.defaultWriteObject();
8. out.writeInt(age);
9. }
10.
11. private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
12. in.defaultReadObject();
13. age = in.readInt();
14. }
15.}
在writeObject()方法中会先调用ObjectOutputStream中的defaultWriteObject()方法,该方法会执行默认的序列化机制,如5.1节所述,此时会忽略掉age字段。然后再调用writeInt()方法显示地将age字段写入到ObjectOutputStream中。readObject()的作用则是针对对象的读取,其原理与writeObject()方法相同。再次执行SimpleSerial应用程序,则又会有如下输出:
1.arg constructor
2.[John, 31, MALE]
必须注意地是,writeObject()与readObject()都是private方法,那么它们是如何被调用的呢?毫无疑问,是使用反射。详情可以看看ObjectOutputStream中的writeSerialData方法,以及ObjectInputStream中的readSerialData方法。
5.3 Externalizable接口
无论是使用transient关键字,还是使用writeObject()和readObject()方法,其实都是基于Serializable接口的序列化。JDK中提供了另一个序列化接口--Externalizable,使用该接口之后,之前基于Serializable接口的序列化机制就将失效。此时将Person类作如下修改,
1.public class Person implements Externalizable {
2.
3. private String name = null;
4.
5. transient private Integer age = null;
6.
7. private Gender gender = null;
8.
9. public Person() {
10. System.out.println("none-arg constructor");
11. }
12.
13. public Person(String name, Integer age, Gender gender) {
14. System.out.println("arg constructor");
15. this.name = name;
16. this.age = age;
17. this.gender = gender;
18. }
19.
20. private void writeObject(ObjectOutputStream out) throws IOException {
21. out.defaultWriteObject();
22. out.writeInt(age);
23. }
24.
25. private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
26. in.defaultReadObject();
27. age = in.readInt();
28. }
29.
30. @Override
31. public void writeExternal(ObjectOutput out) throws IOException {
32.
33. }
34.
35. @Override
36. public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
37.
38. }
39. ...
40.}
此时再执行SimpleSerial程序之后会得到如下结果:
|