The readResolve Method -- 序列化实现readResolve方法的作用

For Serializable and Externalizable classes, the readResolve method allows a class to replace/resolve the object read from the stream before it is returned to the caller. By implementing the readResolve method, a class can directly control the types and instances of its own instances being deserialized. The method is defined as follows: 


ANY-ACCESS-MODIFIER Object readResolve() 
throws ObjectStreamException; 
The readResolve method is called when ObjectInputStream has read an object from the stream and is preparing to return it to the caller. ObjectInputStream checks whether the class of the object defines the readResolve method. If the method is defined, the readResolve method is called to allow the object in the stream to designate the object to be returned. The object returned should be of a type that is compatible with all uses. If it is not compatible, a ClassCastException will be thrown when the type mismatch is discovered. 
For example, a Symbol class could be created for which only a single instance of each symbol binding existed within a virtual machine. The readResolve method would be implemented to determine if that symbol was already defined and substitute the preexisting equivalent Symbol object to maintain the identity constraint. In this way the uniqueness of Symbol objects can be maintained across serialization. 


Note - The readResolve method is not invoked on the object until the object is fully constructed, so any references to this object in its object graph will not be updated to the new object nominated by readResolve. However, during the serialization of an object with the writeReplace method, all references to the original object in the replacement object's object graph are replaced with references to the replacement object. Therefore in cases where an object being serialized nominates a replacement object whose object graph has a reference to the original object, deserialization will result in an incorrect graph of objects. Furthermore, if the reference types of the object being read (nominated by writeReplace) and the original object are not compatible, the construction of the object graph will raise a ClassCastException. 


序列化对象通过流传给调用者,当调用者从ObjectInputStream流中读取序列化对象时,序列化对象返回给调用者之前会先查看是否已经实现这个方法,如果实现那么就返回这个对象的返回值,如果返回值和调用者期望获得的类类型转换不匹配,那么就会报ClassCastException错误。 
但是,前提是,在调用者通过流获取序列化对象时,序列化对象必须已经fully constructed,不然序列化对象不会找这个方法。 


demo: 


  1. public final class Sides implements Serializable {  
  2. private int value;  
  3. private Sides(int newVal) { value = newVal; }  
  4. private static final int LEFT_VALUE = 1;  
  5. private static final int RIGHT_VALUE = 2;  
  6. private static final int TOP_VALUE = 3;  
  7. private static final int BOTTOM_VALUE = 4;  
  8.   
  9. public static final LEFT = new Sides(LEFT_VALUE);  
  10. public static final RIGHT = new Sides(RIGHT_VALUE);  
  11. public static final TOP = new Sides(TOP_VALUE);  
  12. public static final BOTTOM = new Sides(BOTTOM_VALUE);  
  13.   
  14. private Object readResolve() throws ObjectStreamException {  
  15.   // Switch on this instance's value to figure out which class variable  
  16.   // this is meant to match  
  17.   switch(value) {  
  18.    case LEFT_VALUE: return LEFT;  
  19.    case RIGHT_VALUE: return RIGHT;  
  20.    case TOP_VALUE: return TOP;  
  21.    case BOTTOM_VALUE: return BOTTOM;    
  22.   }  
  23.   return null;  
  24. }  
  25. }  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值