Java序列化
序列化:将对象转换为字节序列的过程
反序列化:将字节序列转换为对象的过程
原因:转换为字节序列后,保存字节码文件,方便网络的传输。
Person类
package demo1.serializable; import java.io.Serializable; public class Person implements Serializable { public int id; private static final long serialVersionUID = 1L; // private static final long serialVersionUID = 2L; public Person(int id) { this.id = id; } }
Test测试类
package demo1.serializable; import java.io.*; public class Test { public static void serializablePerson(Person person) throws IOException { ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("file.txt")); out.writeObject(person); System.out.println("序列化成功"); out.close(); } public static Person deserializablePerson(String filePath) throws IOException, ClassNotFoundException { ObjectInputStream in = new ObjectInputStream(new FileInputStream(filePath)); System.out.println("反序列化成功"); return (Person)in.readObject(); } public static void main(String[] args) throws IOException, ClassNotFoundException { Person per = new Person(1); serializablePerson(per); // System.out.println(deserializablePerson("file.txt")); } }
以上序列化、反序列化都成功!
皮一下-1!
1.序列化时设置序列化ID
private static final long serialVersionUID = 1L;
2.修改Person类的序列化ID,进行反序列化
private static final long serialVersionUID = 2L;
最终结果:
Exception in thread "main" java.io.InvalidClassException: demo1.serializable.Person; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1885) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1751) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2042) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1573) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:431) at demo1.serializable.Test.deserializablePerson(Test.java:17) at demo1.serializable.Test.main(Test.java:22)
由此证明:反序列化时:序列化ID不对,是无法序列化成功的。
再皮一下-2
1.序列化时设置序列化ID
private static final long serialVersionUID = 1L;
2.给Person添加属性int age,再反序列化
最终结果:
反序列化成功
Person{id=1, age=0}
害,也就是说,序列化ID是一样的就是无敌咯!!!
再皮一下下-3
1.颠倒id、age的位置
没得用,仔细想想也是没用的,nt了。
突发奇想:反序列化的时候到底是怎么找到对应的字段并赋值的,是构造方法的顺序,还是名字!
1.修改构造方法
序列化时,Person类如下:
package demo1.serializable; import java.io.Serializable; public class Person implements Serializable { public String name; public int id; private static final long serialVersionUID = 1L; public Person(int id) { this.id = id; } @Override public String toString() { return "Person{" + "id=" + id + ", name=" + name + '}'; } }
反序列化时,Person类如下:
package demo1.serializable; import java.io.Serializable; public class Person implements Serializable { public String name; public int id; private static final long serialVersionUID = 1L; public Person(String name) { this.name = name; } @Override public String toString() { return "Person{" + "id=" + id + ", age=" + id + '}';
}
由此证明:反序列化,是通过属性名来找到对应的属性值来反序列化的!!!
另外:
序列化使用:ObjectOutputStream类
反序列化使用:ObjectInputStream类