1700439290
1700439291
(1)类描述信息
1700439292
1700439293
包括包路径、继承关系、访问权限、变量描述、变量访问权限、方法签名、返回值,以及变量的关联类信息。要注意的一点是,它并不是class文件的翻版,它不记录方法、构造函数、static变量等的具体实现。之所以类描述会被保存,很简单,是因为能去也能回嘛,这保证反序列化的健壮运行。
1700439294
1700439295
(2)非瞬态(transient关键字)和非静态(static关键字)的实例变量值
1700439296
1700439297
注意,这里的值如果是一个基本类型,好说,就是一个简单值保存下来;如果是复杂对象,也简单,连该对象和关联类信息一起保存,并且持续递归下去(关联类也必须实现Serializable接口,否则会出现序列化异常),也就是说递归到最后,其实还是基本数据类型的保存。
1700439298
1700439299
正是因为这两点原因,一个持久化后的对象文件会比一个class类文件大很多,有兴趣的读者可以自己写个Hello word程序检验一下,其体积确实膨胀了不少。
1700439300
1700439301
总结一下,反序列化时final变量在以下情况下不会被重新赋值:
1700439302
1700439303
通过构造函数为final变量赋值。
1700439304
1700439305
通过方法返回值为final变量赋值。
1700439306
1700439307
final修饰的属性不是基本类型。
1700439308
1700439309
1700439310
1700439311
1700439313
编写高质量代码:改善Java程序的151个建议 建议14:使用序列化类的私有方法巧妙解决部分属性持久化问题
1700439314
1700439315
部分属性持久化问题看似很简单,只要把不需要持久化的属性加上瞬态关键字(transient关键字)即可。这是一种解决方案,但有时候行不通。例如一个计税系统和人力资源系统(HR系统)通过RMI(Remote Method Invocation,远程方法调用)对接,计税系统需要从HR系统获得人员的姓名和基本工资,以作为纳税的依据,而HR系统的工资分为两部分:基本工资和绩效工资,基本工资没什么秘密,根据工作岗位和年限自己都可以计算出来,但绩效工资却是保密的,不能泄露到外系统,很明显这是两个相互关联的类。先来看薪水类Salary类的代码:
1700439316
1700439317
public class Salary implements Serializable{
1700439318
1700439319
private static final long serialVersionUID=44663L;
1700439320
1700439321
//基本工资
1700439322
1700439323
private int basePay;
1700439324
1700439325
//绩效工资
1700439326
1700439327
private int bonus;
1700439328
1700439329
public Salary(int_basePay, int_bonus){
1700439330
1700439331
basePay=_basePay;
1700439332
1700439333
bonus=_bonus;
1700439334
1700439335
}
1700439336
1700439337
/*getter/setter方法省略*/
1700439338
1700439339
}
[
上一页 ]
[ :1.70043929e+09 ]
[
下一页 ]