java对象序列化和反序列化
 1847

java对象序列化和反序列化

倍速播放下载收听

00:00
07:53

1)什么是对象序列化和反序列化  
     把对象转换为 字节序列的过程称为 对象的序列化。
  把字节序列  恢复为对象的过程称为 对象的反序列化。
  对象的序列化主要有两种用途:
  1) 把对象的字节序列 永久地保存到硬盘上,通常存放在一个文件中;
  2) 在网络上 传送对象的字节序列。
2)具体使用场景  
  在很多应用中,需要对某些对象进行序列化,让它们离开内存空间,入住物理硬盘,以便长期保存。
    比如:
    一、最常见的是Web服务器中的Session对象,当有 10万用户并发访问,就有可能出现10万个Session对象,内存可能吃不消,
    于是Web容器就会把一些seesion先序列化到硬盘中,等要用了,再把保存在硬盘中的对象还原到内存中。
    二、 RPC应用,比如 Dubbo hession等
  当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。   发送方需要把这个Java对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为Java对象。
3)怎么使用  (JDK类库中的序列化API)
     只有实现了Serializable和Externalizable接口的类的对象才能被序列化。
             Externalizable接口继承自 Serializable接口, 实现Externalizable接口的类完全由自身来控制序列化的行为,可以指定序列化哪些属性。
            实现Serializable接口的类可以 采用默认的序列化方式 。  
  对象序列化使用 ObjectOutputStream ,具体使用步骤:
  1) 创建一个对象输出流,它可以包装一个其他类型的目标输出流,如文件输出流;
  2) 通过对象输出流的writeObject(Object obj)方法写到一个目标输出流中。
  对象反序列化使用ObjectInputStream ,具体使用步骤:
  1) 创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
  2) 通过对象输入流的readObject()方法读取对象。
  
  3)注意点
     实现Serializable接口的类,经常会出现警告提示:
Eclipse就会有这个提示:The serializable class User does not declare a static final serialVersionUID field of type long,意思就是说让你添加一个serialVersionUID的值。
  使用补全功能就会添加一行代码 private static final long serialVersionUID = 1L;
serialVersionUID他有什么作用呢?
   serialVersionUID: 字面意思上是序列化的版本号,凡是实现Serializable接口的类都有一个表示序列化版本标识符的静态变量
   Java的序列化机制是通过判断类的serialVersionUID来验证版本一致性的。
   在进行反序列化时,JVM会把传来的字节流中的serialVersionUID与本地相应实体类的serialVersionUID进行比较,
  如果相同就认为是一致的,可以进行反序列化, 否则就会出现序列化版本不一致的异常,即是Invalid Cast Exception。
      具体实例?比如我们写rpc程序,远端和本地都有一个类user,类都实现了Serializable,可以被序列化。远端有一个同样类,有一天远端要在类上打印一下日志,加了一行代码,远端程序反序列化的时候就会报 Invalid Cast Exception  。如果这两个类都写了serialVersionUID而且值一致就可以正常反序列化。如果不写serialVersionUID,编译器会根据这个类的结构(成员变量,成员变量的个数等),生成一个hash值,然后将这个值作为serialVersionUID。所以类的结构有变化hash值就不一样,就会出现报错的现象。
     虚拟机是否允许反序列化,取决于类路径和功能代码是否一致,两个类的序列化 ID 是否一致(就是 private static final long serialVersionUID = 1L) 


     除此之外还有几点要注意:
           1 序列化保存的是对象的状态,静态变量属于类的状态,序列化并不保存静态变量
           2 Transient 关键字的作用是控制变量的序列化,在变量声明前加上该关键字,
           可以阻止该变量被序列化到文件中,在被反序列化后,transient 变量的值被设为初始值,如 int 型的是 0,对象型的是 null 
--------------------- 
作者:zhangkang65 
来源:CSDN 
原文:https://blog.csdn.net/zhangkang65/article/details/86744423 
版权声明:本文为博主原创文章,转载请附上博文链接!

评论

    还没有评论,快来发表第一个评论!

打开喜马拉雅,发表评论