由于若是不实现序列化,那么则没法反序列化java
- 须要存储对象,好比说我如今须要把内存中的对象暂时写入硬盘,等我系统启用时在加载到内存反序列化后继续使用。
- 须要远程传输对象,则须要实现序列化接口,大多在socket网络套接字编程场景中比较常见, 有同窗可能说,我常常使用socket传输数据,确没有实现序列化接口,由于不少状况下咱们都是传输的String字符串,而在Java中String已经实现了Serializable接口
序列化常见出错问题?编程
不实现序列化接口进行保存对象会出现以下错误,能够经过实现Serializable接口解决问题。网络
Exception in thread "main" java.io.NotSerializableException: home.s.Rule at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1184) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:348) at home.s.Serial.main(Serial.java:13) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
修改序列号id则会出现以下问题:
Exception in thread "main" java.io.InvalidClassException: home.s.Rule; local class incompatible: stream classdesc serialVersionUID = 1234000, local class serialVersionUID = 123400 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1630) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373) at home.s.DESerial.main(DESerial.java:13) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
出现这个问题是由于序列号被认为改动致使。这时可能大多数同窗会说,可不能够不使用序列号,而使用Java自己默认的。 以下是Java默认生成序列号源码,大概意思请自行阅读。
/** * Return the serialVersionUID for this class. The serialVersionUID * defines a set of classes all with the same name that have evolved from a * common root class and agree to be serialized and deserialized using a * common format. NonSerializable classes have a serialVersionUID of 0L. * * @return the SUID of the class described by this descriptor */ public long getSerialVersionUID() { // REMIND: synchronize instead of relying on volatile? if (suid == null) { suid = AccessController.doPrivileged( new PrivilegedAction<Long>() { public Long run() { return computeDefaultSUID(cl); } } ); } return suid.longValue(); }
可是这里仍是强烈建议使用一个序列化版本号,由于默认的版本号很是敏感,而且依赖于编译器,若是实体类在序列化以前和以后数据结构有所改变,则会致使以下问题:
Exception in thread "main" java.io.InvalidClassException: home.s.Rule; local class incompatible: stream classdesc serialVersionUID = -1031401772392262459, local class serialVersionUID = 7635324993874063726 at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616) at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1630) at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373) at home.s.DESerial.main(DESerial.java:13) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
具体测试源码以下:数据结构
实体类:app
package home.s; import java.io.Serializable; public class Rule implements Serializable{ private static final long serialVersionUID = 1234000L; public Rule(Long id, String type) { this.id = id; this.type = type; } private Long id; private String type; // private String name; public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getType() { return type; } public void setType(String type) { this.type = type; } /* public String getName() { return name; } public void setName(String name) { this.name = name; }*/ }
序列化
Rule rule = new Rule(1232L, "asdf"); FileOutputStream fileOutputStream = new FileOutputStream(new File("d:\\222.txt")); ObjectOutputStream oos = new ObjectOutputStream(fileOutputStream); oos.writeObject(rule); oos.flush(); fileOutputStream.close();
反序列化
FileInputStream fis = new FileInputStream(new File("D:\\222.txt")); ObjectInputStream ois = new ObjectInputStream(fis); Rule o = (Rule) ois.readObject(); System.out.println(Json.toJson(o));