😋 最前
实体类中常见到
1
| private static long serialVersionUID = 1L;
|
它表示Java序列化版本号
先简单解释两者的含义:
序列化:将Java对象转化为字节,然后进行网络传输或持久化到磁盘
反序列化:将本地或网络传输来的字节转化为Java对象
⭐️ 具体场景
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
@Data public class User { private String name; private Character sex; private Integer age; public static void main(String[] args) throws IOException { InputStream fin = new FileInputStream("D:\\code\\test.txt"); ObjectInputStream oin = new ObjectInputStream(fin); oin.writeObject(new User("huanghao")); oin.close(); fin.close(); OutpuStream fout = new FileOutputStream("D:\\code\\test.txt"); ObjectOutpuStream oout = new ObjectOutpuStream(fout); User user = (User)oout.readObject(); System.out.println(user); oout.close(); fout.close(); } }
|
看上去没问题,但假如User类升级,该类V1版本是三个属性字段(name,sex,age),V2版本时新增一个属性字段(salary),在V1版本时写入磁盘,在V2版本时读取磁盘,则会报InvalidClassException异常,就好比手中的旧船票已经登不上新客船。
🌈 解决方案
User类虽升级,但并不该影响序列化与反序列化(可理解为写入,升级后还能成功读出)。如何解决?引入版本号serialVersionUID即可。引入该类需要实现接口Serializable(本质是在告诉JDK该类要序列化)
1 2 3 4 5 6 7 8 9 10 11 12 13
|
@Data public class User implements Serializable{ private static long serialVersionUID = 1234567890123456789L; private String name; private Character sex; private Integer age; private Double salary; }
|
(ps:IDEA有自动生成版本号的选项,自行百度)
⛄️ 更多
如果想在序列化时屏蔽某字段,可用transient关键字来修饰
1
| private transient Double salary;
|
这样一来,salary虽然还在实体类中,但salary不会被写入到本地磁盘的文件中