Java常见序列化与反序列方法总结(二)

2014-11-24 09:44:07 · 作者: · 浏览: 1
进行反序列化的时候,那些从超类继承的实例变量的值是什么?
Java中的序列化处理实例变量只会在所有实现了Serializable接口的继承支路上展开。所以当一个类进行反序列化处理的时候,超类没有实现Serializable接口,那么从超类继承的实例变量会通过为实现序列化接口的超类的构造函数进行初始化。
7) Can you Customize Serialization process or can you override default Serialization process in Java
7)你能够自定义序列化处理的代码吗或者你能重载Java中默认的序列化方法吗?
答案是肯定的,可以。我们都知道可以通过ObjectOutputStream中的writeObject()方法写入序列化对象,通过ObjectInputStream中的readObject()读入反序列化的对象。这些都是Java 虚拟机提供给你的两个方法。如果你在你的类中定义了这两个方法,那么JVM就会用你的方法代替原有默认的序列化机制的方法。你可以通过这样的方式类自定义序列化和反序列化的行为。需要注意的一点是,最好将这两个方法定义为private,以防止他们被继承、重写和重载。也只有JVM可以访问到你的类中所有的私有方法,你不用担心方法私有不会被调用到, Java序列化过程会正常工作。
8)假设一个新的类的超类实现了Serializable接口,那么如何让这个新的子类不被序列化?
如果一个超类已经序列化了,那么无法通过是否实现什么接口的方式再避免序列化的过程了,但是也还有一种方式可以使用。那就是需要你在你的类中重新实现writeObject()和readObject()方法,并在方法实现中通过抛出NotSerializableException。
9)在Java进行序列化和反序列化处理的时候,哪些方法被使用了?
这个是面试中常见的问题,主要用来考察你是否对readObject()、writeObject()、readExternal()和writeExternal()方法的使用熟悉。Java序列化是通过java.io.ObjectOutputStream这个类来完成的。这个类是一个过滤器流,这个类完成对底层字节流的包装来进行序列化处理。我们通过ObjectOutputStream.writeObject(obj)进行序列化,通过ObjectInputStream.readObject()进行反序列化。对writeObject()方法的调用会触发Java中的序列化机制。readObject()方法用来将已经持久化的字节数据反向创建Java对象,该方法返回Object类型,需要强制转换成你需要的正确类型。
10) Suppose you have a class which you serialized it and stored in persistence and later modified that class to add a new field. What will happen if you deserialize the object already serialized
10)假设你有一个类并且已经将这个类的某一个对象序列化存储了,那么如果你在这个类中加入了新的成员变量,那么在反序列化刚才那个已经存在的对象的时候会怎么样?
这个取决于这个类是否有serialVersionUID成员。通过上面的,我们已经知道如果你的类没有提供serialVersionUID,那么编译器会自动生成,而这个serialVersionUID就是对象的hash code值。那么如果加入新的成员变量,重新生成的serialVersionUID将和之前的不同,那么在进行反序列化的时候就会产生java.io.InvalidClassException的异常。这就是为什么要建议为你的代码加入serialVersionUID的原因所在了。