序列化的坑InvalidClassException

序列化的坑

  • 实体类的信息需要持久化,实现了接口serializable,但没有指定值private static final long serialVersionUID;在之后使用的时候文件在服务器上但即使读取不到。

serializable 是一个标记,java中类要序列化必须实现这个接口;不默认实现可能是为了安全。

    public class StageInfo implements Serializable {
        /**
         * stage 排序编号,从0开始
         **/
        private Integer number;
   
        /**
         * stage ID
         **/
        private String id;
        ...
    }
  • 读文件,很老的代码
    public static  <E> List<E> readObjectForList(String filePath) {
        E [] object;
        File file = new File(filePath);
        if (file.exists()) {
            try(ObjectInputStream out = new ObjectInputStream(new FileInputStream(file))) {
                object = (E[]) out.readObject();
                return Arrays.asList(object);
            }
            catch (IOException e) {
                log.error("文件解析失败" + e.getMessage());
                e.printStackTrace();
            }
            catch (ClassNotFoundException e) {
                log.error("文件解析失败" + e.getMessage());
                e.printStackTrace();
            }
        }
        return null;
    }
  • 经看日志发现异常java.io.InvalidClassException,这是序列化相关异常
    加上private static final long serialVersionUID = 2531697581628090341L;后读取日志报错如下
文件解析失败cn.xxx.pipeline.stageandstep.entity.StageParallelInfo; local class incompatible: stream classdesc serialVersionUID = -7979539792943633706, local class serialVersionUID = 1957675234537638335
  java.io.InvalidClassException: cn.xxx.pipeline.stageandstep.entity.StageParallelInfo; local class incompatible: stream classdesc serialVersionUID = -7979539792943633706, local class serialVersionUID = 1957675234537638335

由于序列化id不同已经读不到了。

复盘

● 如果不加serialVersionUID,也能进行持久化因为系统会默认生成一个id,但是当类发生变化或者编译器发生变化,默认的id会改变就会导致反序列化失败。
● serialVersionUID的取值是Java运行时环境根据类的内部细节自动生成的。如果对类的源代码作了修改,再重新编译,新生成的类文件的serialVersionUID的取值有可能也会发生变化。
● 类的serialVersionUID的默认值完全依赖于Java编译器的实现,对于同一个类,用不同的Java编译器编译,有可能会导致不同的 serialVersionUID,也有可能相同。为了提高serialVersionUID的独立性和确定性,强烈建议在一个可序列化类中显示的定义serialVersionUID,为它赋予明确的值。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值