Java:为什么不反序列化调用构造函数和什么是最好的解决方法? [英] Java: Why doesn't deserialization invoke constructor & what's the best workaround?

查看:862
本文介绍了Java:为什么不反序列化调用构造函数和什么是最好的解决方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Java 1.5的 Java序列化规范说明:


对于可序列化对象,运行第一个
非序列化超类型的无参构造函数。对于可序列化类,
字段初始化为适合其类型的默认值。
然后通过调用
defaultReadObject方法,通过调用特定于类的
readObject方法来恢复每个类的字段,或者如果没有定义这些字段。注意,在
反序列化期间,字段初始化器和
构造函数不会对可序列化类执行。


如果我们在类中放置一个静态变量(例如计数器变量),它将不会像通常那样更新:

  class Foo {
static int t;

public Foo(){
t ++;
}
}

public class Bar extends Foo implements Serializable {
static int t;

public Bar(){
t ++;
}
}

在这种情况下,如果一个实例 Bar 反序列化,则 Foo 的计数器正确, Bar 是一个一个。



我不知道为什么反序列化不会调用构造函数?由于似乎虽然这将获得一点速度,它可能会导致潜在的问题。编译器可以很容易地被设计为产生一个静态构造函数,它只更新将被更新的静态变量,并且当类被加载时不依赖于外部信息。



另外,我不知道什么是最好的方法来避免这一点?



感谢任何输入!

p>

The Java serialization spec for Java 1.5 said:

For serializable objects, the no-arg constructor for the first non-serializable supertype is run. For serializable classes, the fields are initialized to the default value appropriate for its type. Then the fields of each class are restored by calling class-specific readObject methods, or if these are not defined, by calling the defaultReadObject method. Note that field initializers and constructors are not executed for serializable classes during deserialization.

However, this means if we put a static variable (for example a counter variable) inside the class, it will not be updated as normally would:

class Foo {
    static int t;

    public Foo() {
        t++;
    }
}

public class Bar extends Foo implements Serializable {
    static int t;

    public Bar() {
        t++;
    }
}

In this case, if one instance of Bar is deserialized, then the counter for Foo is correct and the counter for Bar is off-by-one.

I wonder why does deserialization does not invoke the constructor? Since it seems that while this will gain a bit on speed, it can cause potential problems. The compiler could be easily designed to produce a "static constructor" that only updates the static variables that will be updated and does not rely on outside information when the class is loaded.

Also, I wonder what is the best way to avoid this? The solution I can think of is packing the deserialization with the operation on the static variable.

Thanks for any inputs in advance!

解决方案

Deserialization doesn't invoke the constructor because the purpose of it is to express the state of the object as it was serialized, running constructor code could interfere with that.

这篇关于Java:为什么不反序列化调用构造函数和什么是最好的解决方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆