打字猴:1.7004391e+09
1700439100
1700439101 private static final long serialVersionUID=XXXXXL;
1700439102
1700439103 而隐式声明则是我不声明,你编译器在编译的时候帮我生成。生成的依据是通过包名、类名、继承关系、非私有的方法和属性,以及参数、返回值等诸多因子计算得出的,极度复杂,基本上计算出来的这个值是唯一的。
1700439104
1700439105 serialVersionUID如何生成已经说明了,我们再来看看serialVersionUID的作用。JVM在反序列化时,会比较数据流中的serialVersionUID与类的serialVersionUID是否相同,如果相同,则认为类没有发生改变,可以把数据流load为实例对象;如果不相同,对不起,我JVM不干了,抛个异常InvalidClassException给你瞧瞧。这是一个非常好的校验机制,可以保证一个对象即使在网络或磁盘中“滚过”一次,仍能做到“出淤泥而不染”,完美地实现类的一致性。
1700439106
1700439107 但是,有时候我们需要一点特例场景,例如:我的类改变不大,JVM是否可以把我以前的对象反序列化过来?就是依靠显式声明serialVersionUID,向JVM撒谎说“我的类版本没有变更”,如此,我们编写的类就实现了向上兼容。我们修改一下上面的Person类,代码如下:
1700439108
1700439109 public class Person implements Serializable{
1700439110
1700439111 private static fnal long serialVersionUID=55799L;
1700439112
1700439113 /*其他保持不变*/
1700439114
1700439115 }
1700439116
1700439117 刚开始生产者和消费者持有的Person类版本一致,都是V1.0,某天生产者的Person类版本变更了,增加了一个“年龄”属性,升级为V2.0,而由于种种原因(比如程序员疏忽、升级时间窗口不同等)消费端的Person还保持为V1.0版本,代码如下:
1700439118
1700439119 public class Person implements Serializable{
1700439120
1700439121 private static final long serialVersionUID=5799L;
1700439122
1700439123 private int age;
1700439124
1700439125 /*age、name的getter/setter方法省略*/
1700439126
1700439127 }
1700439128
1700439129 此时虽然生产者和消费者对应的类版本不同,但是显式声明的serialVersionUID相同,反序列化也是可以运行的,所带来的业务问题就是消费端不能读取到新增的业务属性(age属性)而已。
1700439130
1700439131 通过此例,我们的反序列化实现了版本向上兼容的功能,使用V1.0版本的应用访问了一个V2.0版本的对象,这无疑提高了代码的健壮性。我们在编写序列化类代码时,随手加上serialVersionUID字段,也不会给我们带来太多的工作量,但它却可以在关键时候发挥异乎寻常的作用。
1700439132
1700439133 注意 显式声明serialVersionUID可以避免对象不一致,但尽量不要以这种方式向JVM“撒谎”。
1700439134
1700439135
1700439136
1700439137
1700439138 编写高质量代码:改善Java程序的151个建议 [:1700438079]
1700439139 编写高质量代码:改善Java程序的151个建议 建议12:避免用序列化类在构造函数中为不变量赋值
1700439140
1700439141 我们知道带有final标识的属性是不变量,也就是说只能赋值一次,不能重复赋值,但是在序列化类中就有点复杂了,比如有这样一个类:
1700439142
1700439143 public class Person implements Serializable{
1700439144
1700439145 private static final long serialVersionUID=71282334L;
1700439146
1700439147 //不变量
1700439148
1700439149 public fnal String name=“混世魔王”;
[ 上一页 ]  [ :1.7004391e+09 ]  [ 下一页 ]