博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一次搞懂序列化和反序列化
阅读量:6977 次
发布时间:2019-06-27

本文共 5258 字,大约阅读时间需要 17 分钟。

hot3.png

  1. 为什么需要序列化?

因为如果不实现序列化,那么则无法反序列化

  1. 序列化使用场景?
  1. 需要存储对象,比如说我现在需要把内存中的对象暂时写入硬盘,等我系统启用时在加载到内存反序列化后继续使用。
  2. 需要远程传输对象,则需要实现序列化接口,大多在socket网络套接字编程场景中比较常见, 有同学可能说,我经常使用socket传输数据,确没有实现序列化接口,因为很多情况下我们都是传输的String字符串,而在Java中String已经实现了Serializable接口
  1. 序列化常见出错问题?

    不实现序列化接口进行保存对象会出现如下错误,可以通过实现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
() { 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)
  1. 具体测试源码如下:

    实体类:

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));

转载于:https://my.oschina.net/u/1787735/blog/3047896

你可能感兴趣的文章
URAL 2027 URCAPL, Episode 1 (模拟)
查看>>
hadoop install start-dfs.sh 失败
查看>>
各种小记
查看>>
Java关键字final、static使用总结
查看>>
Bootstrap 模态框上下居中
查看>>
SQL Server不能启动
查看>>
【Vue】IView之table组件化学习(二)
查看>>
使用reflector对.NET反编译
查看>>
JAVA-基础(Class对象及反射)
查看>>
unity加载ab后,场景shader不起效问题(物件表现黑色)
查看>>
框架页面jquery装载
查看>>
捕获Camera并保存图片到本地(照相功能) -samhy
查看>>
OTS parsing error: invalid version tag woff和ttf文件被Filter拦截
查看>>
SpringMvc+ajax实现文件跨域上传
查看>>
hive基本操作与应用
查看>>
jenkins自动化部署工具
查看>>
Unique Binary Search Trees java实现
查看>>
Django内置Admin
查看>>
一个疯狂想法
查看>>
ARM体系结构
查看>>