序列化对象和反序列化对象
场景描述:
在topnotify项目中定义了一个抽象类PcNotify,也定义了他的子类PcNotifyTrade,PcNotifyTrade对象需要被发送到Napoli queue(Napoli是阿里的异步调用框架,以消息队列为中心), 需要被序列化,PcNotify实现了序列化接口。
数聚宝项目中需要消费这个queue,也定义这个抽象类和他的子类,类名、包名和属性都一样,PcNotify也实现了序列化接口,
这里需要反序列化成对象。
(1) 两个PcNotifyTrade类序列化ID相同,他们的父类都没有序列化ID。
(2) 两个PcNotifyTrade类序列化ID相同,topnotify项目中的PcNotify有序列化ID=1L,数聚宝项目中的PcNotify没有。
(3) 两个PcNotifyTrade类序列化ID不同,他们的父类都有相同的序列化ID。
(1)的现象:
数聚宝消费消息时反序列化成功。
(2)的现象:
反序列化失败,抛异常:
14:10:38,200 INFO [STDOUT] 2012-05-28 14:10:38,199 [DefaultAsyncReceiver.java:544] ERROR - handle msg failed: Failed to build body from bytes. Reason:
java.io.InvalidClassException: com.alibaba.tnpc.service.pcnotify.interfaces.beans.PcNotify; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = -4106756048636601389
(3)的现象:
反序列化失败,抛异常:
14:36:16,290 INFO [STDOUT] 2012-05-28 14:36:16,289 [DefaultAsyncReceiver.java:544] ERROR - handle msg failed: Failed to build body from bytes. Reason:
java.io.InvalidClassException: com.alibaba.tnpc.service.pcnotify.interfaces.beans.PcNotifyTrade; local class incompatible: stream classdesc serialVersionUID =
1450252723065615615, local class serialVersionUID = 145025272306561561
结论:
(1) 序列化某个对象时,需要实现序列化接口、需要serialVersionUID以及被序列化的对象serialVersionUID要和反序列化的对象一致,他们的父类可以都没有serialVersionUID。
(2) 序列化某个对象时,被序列化的对象的父类有serialVersionUID ,如果反序列化的对象没有serialVersionUID,此时JVM会随机产生一个。他们的父类要么都没有
serialVersionUID,如果有一定要相同。
(3) 序列化某个对象时,即使他们的父类都有serialVersionUID,且相同,被序列化的对象和反序列化的对象本身也一定需要serialVersionUID,且两者相同。