下面的代码是如何工作的?
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。
对这种行为有什么解释吗?
a
的默认值为10 -在创建对象时将其设置为10。如果你想有一个实际的测试,在实例化后设置它为一个不同的值,然后序列化它。
至于你的更新-如果一个类是不可序列化的,它的字段不序列化和反序列化。
由于B
扩展了A
,因此是 A
。这意味着b instanceof Serializable
返回true
。
因此,只要您尝试序列化的对象在instanceof Serializable
检查中返回true,您就可以序列化它。这适用于包含在此对象本身中的任何复合对象。
但是你不能在执行A a = new A();
的同时尝试序列化a
。
考虑一下:
java.lang.Object
不实现Serializable
。因此,在这种情况下,没有人能够在Java中序列化任何对象!然而,事实并非如此。此外,在涉及多个JavaBeans扩展公共超类型的项目中,一般做法是使该超类型实现Serializable
,以便所有子类都不必这样做。
如果类B扩展了类A,而类A是不可序列化的,那么在类B反序列化之后,类A的所有实例变量都将被初始化为它们的默认值(在这种情况下是10)。
如果你是一个可序列化的类,但是你的超类是不可序列化的,那么你从该超类继承的任何实例变量将被重置为它们在初始构造对象时给出的值。这是因为不可序列化的类构造函数将运行!事实上,在第一个非序列化类构造函数之上的每个构造函数也将运行,无论如何,因为一旦第一个超级构造函数被调用,(在反序列化期间),它当然会调用它的超级构造函数,以此类推继承树。
如果父类不可序列化,则在每次反序列化时初始化其字段。即对象仍然需要被构造