关于 Java 序列化的一些面试问题的回答

问题原贴请见:http://www.oschina.net/bbs/thread/18750

 

 

Java中,一切都是对象,在分布式环境中经常需要将Object从这一端网络或设备传递到另一端。 这就需要有一种可以在两端传输数据的协议。Java序列化机制就是为了解决这个问题而产生。而java所有支持对象序列化的类需要实现Serizlizable接口。


1) Serializable 和 Externalizable 接口有何不同?

答:Externalizable 接口也是用于实现类的序列化的;但Externalizable提供了writeExternal ()和 readExternal () 方法,这使得我们可以灵活地控制java序列化机制,而非依赖于java的默认机制。

2) Serializable 接口有几个方法? 如果没有方法,那么为什么会有这样的接口?

答:Serializable 接口没有方法,该接口只是一个标识器接口,标识实现该接口的类是可序列化的。

3) serialVersionUID 有何用途? 如果没定义会有什么问题?

答:SerialVersionUID 是定义在类中的public static final 常量。如果你没有显示指定,当该实例对象持久化式,java编译器自动生成一个SerialVersionUID。系统生成UID是会考虑到类的属性的(具体表现为类的hashcode). 如果没有指定SerialVersionUID,当类的成员有变化会导致系统重新产生一个SerialVersionUID,而旧的实例化的类对象将无法正确的还原出状态。Java序列化过程时,依据正确的SerialVersionUID来还原序列化对象的状态。

4) 如果你不希望某些成员被序列化,应该怎么做?

答:标识该成员为transient,即序列化时跳过该成员

5) 序列化某个对象时,如果某个成员没有实现 Serializable 会怎样?

答:直接跳过该成员

6) 如果某个类实现了 Serializable ,但父类没实现,那么当执行反序列化的时候,对象状态是怎样的?

答:在反序列化时, 非序列化父类的构造函数将运行,使得子类从父类继承的任何实例变量将被重置而非还原。而子类的成员变量状态将还原。

7) 能否自定义序列化的过程?

答:Java提供了一种特殊的机制,即两个私有方法:writeObjet、readObject。当在类中实现了它们,在序列化和反序列化时会自动调用这些方法。方法签名如下:

public void writeObject (ObjectOutputStream os); public void readObject (ObjectInputStream os); 


8) 如果超类实现了 Serializable,那么子类如何避免被序列化?

答:为了避名子类序列化,你可以在重写writeObjet、readObject方法,在方法中抛出NotSerializableException 异常。

9) Java 在进行对象序列化和反序列化的时候,用到了哪个方法?

答:  ObjecInputStream.readObject() ,  ObjectOutputStream.writeObject(obj) 

10) 如果你已经将某个类的实例序列化到磁盘,这时候再往这个类添加新的属性,那么反序列化该对象的时候会发生什么?

答:见问题3

11) 什么是 Java 序列化机制中的兼容和不兼容的变化?

答:见英文答案。

12) 能否通过网络来传输序列化对象?

答: 可以使用TCP、UDP等协议传输序列化对象。

13) 什么类型的变量不会被序列化?

答: 静态类型和transient 变量。

 

英文答案:http://javarevisited.blogspot.com/2011/04/top-10-java-serialization-interview.html

补充:

  • 继承如何影响序列化:如果超类是序列化的,根据java接口规则,该类的所有子类都会自动隐匿实现Serializable.
  • 序列化不适用于静态变量
     

 

你可能感兴趣的:(Java)