昆明java培训
达内昆明广州春城路

18487146383

热门课程

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

  • 时间:2016-09-30
  • 发布:昆明Java培训
  • 来源:达内新闻

昆明Java培训机构的老师知道带有final标识的属性是不变量,也就是只能赋值一次,不能重复赋值,但是在序列化类中就有点复杂了,比如这个类:

1 public class Person implements Serializable {

2    private static final long serialVersionUID = 1867341609628930239L;

3    public final String perName="程咬金";

4}

这个Peson类(此时V1.0版本)被序列化,然后存储在磁盘上,在反序列化时perName属性会重新计算其值(这与static变量不同,static变量压根就没有保存到数据流中)比如perName属性修改成了"秦叔宝"(版本升级为V2.0),那么反序列化的perName值就是"秦叔宝"。保持新旧对象的final变量相同,有利于代码业务逻辑统一,这是序列化的基本原则之一,也就是说,如果final属性是一个直接量,在反序列化时就会重新计算。对于基本原则不多说,现在说一下final变量的另一种赋值方式:通过构造函数赋值。代码如下:

public class Person implements Serializable {

private static final long serialVersionUID = 1867341609628930239L;

public final String perName;

public Person() {

perName = "程咬金";

}

}

这也是我们常用的一种赋值方式,可以把Person类定义为版本V1.0,然后进行序列化,看看序列化后有什么问题,序列化代码如下:

public class Serialize {

public static void main(String[] args) {

//序列化以持久保持

SerializationUtils.writeObject(new Person());

}

}

Person的实习对象保存到了磁盘上,它时一个贫血对象(承载业务属性定义,但不包含其行为定义),我们做一个简单的模拟,修改一下PerName值代表变更,要注意的是serialVersionUID不变,修改后的代码如下:

public class Person implements Serializable {

private static final long serialVersionUID = 1867341609628930239L;

public final String perName;

public Person() {

perName = "秦叔宝";

}

}

此时Person类的版本时V2.0但serialVersionUID没有改变,仍然可以反序列化,代码如下:

public class Deserialize {

public static void main(String[] args) {

Person p = (Person) SerializationUtils.readObject();

System.out.println(p.perName);

}

}

现在问题出来了,打印出来的结果是"程咬金"还是"秦叔宝"?答案是:"程咬金"。final类型的变量不是会重新计算嘛,打印出来的应该是秦叔宝才对呀。为什么会是程咬金?这是因为这里触及到了反序列化的两一个原则:反序列化时构造函数不会执行.

反序列化的执行过程是这样的:JVM从数据流中获取一个Object对象,然后根据数据流中的类文件描述信息(在序列化时,保存到磁盘的对象文件中包含了类描述信息,注意是描述信息,不是类)查看,发现是final变量,需要重新计算,于是引用Person类中的perName值,而此时JVM又发现perName竟没有赋值,不能引用,于是它很聪明的不再初始化,保持原值状态,所以结果就是"程咬金"了。

注意:在序列化类中不使用构造函数为final变量赋值.

了解详情请登陆昆明达内Java培训官网(km.Java.tedu.cn)!

上一篇:java培训:显示声明UID
下一篇:避免为final变量复杂赋值

电脑编程学什么专业好?java好吗?【达内java培训】

上java培训有用吗?怎么衡量?【达内培训】

昆明java培训机构怎么选?昆明达内java培训怎么样?

学Java自学还是达内培训机构好?

选择城市和中心
贵州省

广西省

海南省

台湾