一、概念
序列化:把对象转换为字节序列的过程
反序列化:把字节序列恢复为对象的过程
二、用途
1、将对象持久化到物理硬盘上,通常文件方式存在;
2、在网络上传输对象的字节序列。
三、试验
例子中使用
java.io.ObjectOutputStream将对象进行序列化,使用
java.io.ObjectInputStream将对象进行反序列化。
1、普通java类未实现Serializable接口
测试实体类SmallDog.java |
public class SmallDog { private String name; private Double weight; private int age; public SmallDog() { } public SmallDog(String name, Double weight, int age) { this.name = name; this.weight = weight; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getWeight() { return weight; } public void setWeight(Double weight) { this.weight = weight; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } |
将SmallDog进行序列化代码片段 |
public void testUnImplSeralizable(){ com.smalldog.unimplseralizable.SmallDog smallDog = new com.smalldog.unimplseralizable.SmallDog("小白", 4.0, 1); try { FileOutputStream fos = new FileOutputStream("unimplseralizable.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(smallDog); oos.flush(); oos.close(); } catch (IOException e) { e.printStackTrace(); } } |
输出结果 |
java.io.NotSerializableException: com.smalldog.unimplseralizable.SmallDog at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:347) at com.smalldog.SerializableTestCase.testUnImplSeralizable(SerializableTestCase.java:19) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) at org.junit.runners.ParentRunner.run(ParentRunner.java:236) at org.junit.runner.JUnitCore.run(JUnitCore.java:157) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:234) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:74) |
2、普通java类实现Serializable接口
测试实体类SmallDog.java (与以上例子增加了实现接口) |
public class SmallDog implements Serializable{ private String name; private Double weight; private int age; public SmallDog() { } public SmallDog(String name, Double weight, int age) { this.name = name; this.weight = weight; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getWeight() { return weight; } public void setWeight(Double weight) { this.weight = weight; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "SmallDog{" + "name='" + name + '\'' + ", weight=" + weight + ", age=" + age + '}'; } } |
将SmallDog进行序列化代码片段 |
public void testSeralizableSmallDog(){ SmallDog smallDog = new SmallDog("小白", 4.0, 1); try { FileOutputStream fos = new FileOutputStream("unimplseralizable.txt"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(smallDog); oos.flush(); oos.close(); } catch (IOException e) { e.printStackTrace(); } } |
结果输出序列化后的文件:
3、将以上序列化后的文件进行反序列化
反序列化文件seralizable.txt代码片段 |
public void deserializeSmallDog(){ try { SmallDog smallDog = null; FileInputStream fis = new FileInputStream(new File("seralizable.txt")); ObjectInputStream ois = new ObjectInputStream(fis); smallDog = (SmallDog)ois.readObject(); System.out.println(smallDog.toString()); ois.close(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } |
输出结果 |
SmallDog{name='小白', weight=4.0, age=1} |
四、结论
要将对象进行序列化(将对象持久化或网络传输)必须使对象实现
java.io.Serializable接口或者使用其他序列化库,JDK自带序列化并不是效率最高的。