→ 推荐:《刀剑神域-序列之争》
序列化 序列化只保存类的属性信息 反序列化serialversionUID 作用IDEA配置警告 序列化中常见的两类异常 java.io.NotSerializableExceptionjava.io.InvalidClassException 克隆 浅克隆深克隆(序列化)序列化相关类的继承关系用于标记可序列化对象 (private static final long),对指定文件进行反序列化时需要验证源与目标具有相同的UID
java.io.InvalidClassException: xyz.xx.Person; local class incompatible: stream classdesc serialVersionUID = 3437483674491733544, local class serialVersionUID = 2215763102943453354 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1939) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1805) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2096) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1624) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:464) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:422) at xyz.xx.Test.deSerializePerson(Test.java:60) at xyz.xx.Test.main(Test.java:18)如果UID没有显示指明,类会自动根据当前类的信息摘要出一个serialVersionUID,当类的内容发生改变时,该默认生成的UID会发生很大的变化;
IDEA配置警告(未显式定义serialVersionUID时给与警告)
java.io.NotSerializableException
被序列化的类没有实现Serializable接口
java.io.InvalidClassException
反序列化对象UID与本地类UID不匹配
实现Clonable接口
java.lang.CloneNotSupportedException重写Object类中的clone方法
@Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }Person.java
package xyz.xx; import java.io.Serializable; public class Person implements Serializable { private static final long serialVersionUID = 3437483674491733544L; private String name; private int age; private boolean gender; public Person(){} public Person(String name, int age, boolean gender) { this.name = name; this.age = age; this.gender = gender; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public boolean isGender() { return gender; } public void setGender(boolean gender) { this.gender = gender; } }Student.java
package xyz.xx; import java.io.Serializable; public class Student extends Person implements Serializable { private static final long serialVersionUID = -7461432514299767086L; private int score; public Student(){} public Student(String name, int age, boolean gender) { super(name, age, gender); } public int getScore() { return score; } public void setScore(int score) { this.score = score; } @Override public String toString() { return super.getName()+"-"+super.getAge()+"-"+(super.isGender()?"男":"女")+":"+score; } }Teacher.java
内部使用序列化实现deepClone()
package xyz.xx; import java.io.*; public class Teacher extends Person implements Cloneable, Serializable { private static final long serialVersionUID = -1883148076584384389L; private Student student; public Teacher(){} public Teacher(String name, int age, boolean gender, Student student) { super(name, age, gender); this.student = student; } public Student getStudent() { return student; } public void setStudentScore(int score) { this.student.setScore(score); } public Teacher deepClone() throws IOException, ClassNotFoundException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); oos.writeObject(this); ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bais); return (Teacher)ois.readObject(); } @Override public String toString() { return super.getName()+"-"+super.getAge()+"-"+(super.isGender()?"男":"女")+":"+student; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }Test.java
package xyz.xx; /** * 下方两次获取逻辑不同,注意 * * false * true * 学生A-18-女:99 * 学生A-18-女:99 * false * false * 学生A-18-女:199 * 学生A-18-女:99 */ public class Test { public static void main(String[] args) { Student s1 = new Student("学生A",18,false); Teacher t1 = new Teacher("教师A",37,false,s1); try { Teacher t2 = (Teacher)t1.clone(); System.out.println(t1==t2); // true System.out.println(t1.getStudent()==t2.getStudent()); t1.setStudentScore(99); // 修改t1影响t1和t2 System.out.println(t1.getStudent()); System.out.println(t2.getStudent()); Teacher t3 = t1.deepClone(); System.out.println(t1==t3); // false System.out.println(t1.getStudent()==t3.getStudent()); t1.setStudentScore(199); // 修改t1只影响t1 System.out.println(t1.getStudent()); System.out.println(t3.getStudent()); } catch (Exception e) { e.printStackTrace(); } } }