在使用序列化流的时候,是需要给实体类实现Serializable
这个接口类的,它没有抽象方法,这种类型的接口叫标记型接口。只有实现了这个接口,当前类才能被序列化。
在我们实现这个接口的时候,会生成一个隐藏的序列化版本号,在代码中不可见,但是这个版本号非常重要。因为在实际的开发中,业务可能会发生改变,比如需要对实体类的属性进行改动,这个时候,对类的属性修改完后,如果没有给这个实体类加一个序列化版本号,就会报错,如下:
1 | Exception in thread "main" java.io.InvalidClassException: com.long1008.pojo.Student; local class incompatible: stream classdesc serialVersionUID = 3057213877706704592, local class serialVersionUID = 2218238665963421448 |
大致的意思就是前后两个版本号对不上而导致错误,知道了错误,就可以开始对症下药了。既然版本号对不上,那就想办法给这个实体类加上一个版本号,而且是不能改变的。
这里一共列举了三种解决方法:
(1)、第一种方法,是手动加上序列化号,但是变量名必须严格按照指定名字来定义,不推荐
1 | private static final long serialVersionUID = 1L; |
(2)、第二种方法,在设置里面勾选上指定选项,在实现这个接口时,会提示生成序列化号,推荐使用这个方法
1 | private static final long serialVersionUID = 5057213877706704595L; |
(3)、第三种方法,ArrayList这个类也实现了序列化,可以去这个类中复制,修改序列化号即可(不推荐)
注:需要注意的是,序列化版本号必须命名为serialVersionUID,否则可能会因识别不了而导致继续报错!
最后,这里再说一下序列化流的两个细节:
(1)、 transient 标记敏感属性不需要序列化到本地
在实体类中,有一些属性是敏感信息或者不需要序列化到本地文件中的,就可以使用 transient 瞬态关键字来修饰这个属性,表示不需要把这个属性序列化到本地文件。
// transient: 瞬态关键字
// 作用: 不会把当前属性序列化到本地文件中
private transient String address;
(2)、序列化流写到文件中的数据不能修改,一旦修改就再也无法读回来了。