美文网首页
改善Java程序建议12

改善Java程序建议12

作者: KUN叔 | 来源:发表于2017-02-27 15:00 被阅读10次

    建议12:避免用序列化类在构造函数中为不变量赋值

    一般来说,final标识的属性是不变量,也就是说只能赋值一次,不能重复赋值,但是在序列化类中有些不一样。

    public class Person implemnets Serializable{
      private static final long serialVersionUID = 71282334L;
      //不变量
      public final String name = "混世魔王";
    }
    

    这个Person类(此时V1.0版本)被序列化,然后存储在磁盘上,在被反序列化时name属性会重新计算其值,(这与static变量不同,static变量压根就没有保存在数据流中),比如name属性修改成了“德天使”(版本升级为V2.0),那么反序列化对象的name值就是“德天使”。也就是说,如果final属性是一个直接量,在反序列化时就会重新计算。

    接下来看另一种赋值方法:通过构造函数赋值。

    public class Person implements Serializable {
      private static final long serialVersionUID = 91282334L;
      public final String name;
      public Person(){
        name = "混世魔王";
      }
    }
    

    然后进行序列化,然后在修改name="德天使",接着反序列化。结果name仍然是“混世魔王”。

    ** 这里涉及到反序列化的另一个规则:反序列化时构造函数不会执行**

    反序列化的过程是这样的:JVM从数据流中获取一个Object对象,然后根据数据流中的类文件描述信息(在序列化时,保存到磁盘的对象文件中包含了类的描述信息,注意是类描述信息,不是类)查看,发现是final变量,需要重新计算,于是引用Person类中的name值,而此时JVM又发现name竟然没有复制,不能引用,于是它不在初始化,保持原值状态,所以仍然是“混世魔王”。

    相关文章

      网友评论

          本文标题:改善Java程序建议12

          本文链接:https://www.haomeiwen.com/subject/gpyzwttx.html