J2SE中的序列化之接受默认序列化

wang鞋吧

wang鞋吧

2016-02-19 12:30

关注图老师设计创意栏目可以让大家能更好的了解电脑,知道有关于电脑的更多有趣教程,今天给大家分享J2SE中的序列化之接受默认序列化教程,希望对大家能有一点小小的帮助。

  首先要了解Java默认的序列化行为,java将一切关于对象的信息都保存了下了,也就是说,有些时候那些不需要保存的也被保存了下来。一般情况下,我们仅仅需要保存逻辑数据就可以了。不需要保存的数据我们可以用要害字transient标出。
  
  以下是一个例子:
  
  import java.io.*;
  
  public class Serial implements Serializable {
  
   int company_id;
  
   String company_addr;
  
   transient boolean company_flag;
  
  }
  
  则company_flag字段将不会参与序列化与反序列化,但同时你也增加了为他初始值的责任。这也是序列化经常导致的问题之一。因为序列化相当于一个只接受数据流的public构造函数,这种对象构造方法是语言之外的。但他仍然是一种形式上的构造函数。如若你的类不能够通过其他方面来保证初始化,则你需要额外的提供readObject方法,首先正常的反序列化,然后对transient标示的字段进行初始化。
  
  在不适合的时候,使用java默认的序列化行为可能会带来速度上的影响,最糟糕的情况是,可能导致溢出。在某些数据结构的实现中,经常会充斥着各种的循环引用,而java的默认序列化行为,并不了解你的对象结构,其结果就是java试图通过一种昂贵的“图遍历”来保存对象状态。可想而知,不但慢而且可能溢出。这时候你就要提供自己的readObject,来代替默认的行为。
  
  兼容性问题
  
  兼容性历来是复杂而麻烦的问题。
  
  不要兼容性:
  
  首先来看看假如我们的目的是不要兼容性,应该注重哪些。不要兼容性的场合很多,比如war3每当版本升级就不能够读取以前的replays。
  
  兼容也就是版本控制,java通过一个名为UID(stream unique identifier)来控制,这个UID是隐式的,它通过类名,方法名等诸多因素经过计算而得,理论上是一一映射的关系,也就是唯一的。假如UID不一样的话,就无法实现反序列化了,并且将会得到InvalidClassException。
  
  当我们要人为的产生一个新的版本(实现并没有改动),而抛弃以前的版本的话,可以通过显式的声名UID来实现:
  
  private static final long serialVersionUID=****; 你可以编造一个版本号,但注重不要重复。这样在反序列化的时候老版本将得到InvalidClassException,我们可以在老版本的地方捕捉这个异常,并提示用户升级的新的版本。
  
  当改动不大时,保持兼容性(向下兼容性的一个特例):
  
  有时候你的类增加了一些无关紧要的非私有方法,而逻辑字段并不改变的时候,你当然希望老版本和新版本保持兼容性,方法同样是通过显式的声名UID来实现。下面我们验证一下。
  
  老版本:
  
  import java.io.*;
  
  public class Serial implements Serializable {
  
   int company_id;
  
   String company_addr;
  
   public Serial1(int company_id, String company_addr) {
  
  this.company_id = company_id;
  
  this.company_addr = company_addr;
  
   }
  
   public String toString() {
  
  return "DATA: "+company_id+" "+
  
  company_addr;
  
   }
  
  }新版本
  
  import java.io.*;
  
  public class Serial implements Serializable {
  
   int company_id;
  
   String company_addr;
  
   public Serial1(int company_id, String company_addr) {
  
  this.company_id = company_id;
  
  this.company_addr = company_addr;
  
   }
  
   public String toString() {
  
  return "DATA: "+company_id+" "+ company_addr;
  
   }
  
   public void todo(){}//无关紧要的方法
  
  } 首先将老版本序列化,然后用新版本读出,发生错误:
  
  java.io.InvalidClassException: Serial.Serial1; local class incompatible: stream classdesc serialVersionUID = 762508508425139227, local class serialVersionUID = 1187169935661445676 接下来我们加入显式的声名UID:
  
  private static final long serialVersionUID=762508508425139227l; 再次运行,顺利地产生新对象
  
  DATA: 1001 com1
  
  如何保持向上兼容性:
  
  向上兼容性是指老的版本能够读取新的版本序列化的数据流。经常出现在我们的服务器的数据更新了,仍然希望老的客户端能够支持反序列化新的数据流,直到其更新到新的版本。可以说,这是半自动的事情。
  
展开更多 50%)
分享

猜你喜欢

J2SE中的序列化之接受默认序列化

编程语言 网络编程
J2SE中的序列化之接受默认序列化

谈谈J2SE中的序列化之接受默认序列化

编程语言 网络编程
谈谈J2SE中的序列化之接受默认序列化

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

谈谈J2SE中的序列化之当序列化遭遇继承

编程语言 网络编程
谈谈J2SE中的序列化之当序列化遭遇继承

J2SE中的序默认序列化

Java JAVA基础
J2SE中的序默认序列化

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

J2SE中的序列化之继承

Java JAVA基础
J2SE中的序列化之继承

J2SE中的序列化的认识

Java JAVA基础
J2SE中的序列化的认识

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

一辈子要拥有它 - QQ情侣分组

一辈子要拥有它 - QQ情侣分组

用ASP开"多线程"

用ASP开"多线程"
下拉加载更多内容 ↓