以下代码如何运作?
class A {
int a = 10;
}
class B extends A implements Serializable{
}
public class Test {
public static void main(String[] args){
B obj = new B();
obj.a = 25;
//Code to serialize object B (B b= new B()),
// deserialize it and print the value of 'a'.
}
}
即使我在代码中更改了'a'的值,代码也会打印10。
对此行为的任何解释?
答案 0 :(得分:11)
a
的默认值为10 - 创建对象时将设置为10。如果您想进行实际测试,请在实例化后将其设置为不同的值,然后将其序列化。
至于您的更新 - 如果某个类不可序列化,则其字段不会被序列化和反序列化。只有可序列化子类的字段。
答案 1 :(得分:7)
由于B
延伸A
,是 A
。这意味着b instanceof Serializable
会返回true
。
因此,只要您尝试序列化的对象对instanceof Serializable
检查返回true,就可以序列化它。这适用于此对象本身中包含的任何复合对象。
但您无法A a = new A();
并尝试序列化a
。
考虑一下:
java.lang.Object
未实施Serializable
。所以,在这种情况下,没有人能够用Java序列化任何对象!然而,事实并非如此。此外,在涉及多个JavaBeans扩展常见超类型的项目中,通常的做法是使这个超类型实现Serializable
,以便所有子类都不必这样做。
答案 2 :(得分:2)
如果B类扩展了A类,并且A不可序列化,那么在对B类进行反序列化之后,A类的所有实例变量都会使用它们的默认值(在本例中为10)进行初始化。
答案 3 :(得分:1)
如果您是一个可序列化的类,但您的超类不可序列化,那么您从该超类INHERIT的任何实例变量将被重置为在该对象的原始构造期间给出的值。这是因为非序列化类构造函数将运行!实际上,每个构造函数ABOVE第一个非可序列化的类构造函数也将运行,无论如何,因为一旦调用了第一个超级构造函数(在反序列化期间),它当然会调用其超级构造函数,依此类推依赖继承树。
答案 4 :(得分:0)
如果父类不可序列化,则每次反序列化对象时都会初始化其字段。即物体仍然需要建造。