首  页 | 资讯中心 | 网络学院 | 天新汽车 | 天新手机 | 天新游戏 | 软件开发 | 考试认证
品 牌 机 | 笔 记 本 | 服 务 器 | 天新数码 - DC - DV - MP3 - MP4 - GPS - TV | 数字家庭
硬件 DIY - 主板 - CPU - 内 存 - 硬 盘 - 显示器 - 显卡 - 光驱 - 机箱 - 键鼠 - 网络设备
办公设备 | 打 印 机 | 扫 描 仪 | 投 影 仪 | 一 体 机 | 传 真 机 | 路 由 器 | 交 换 机
软件下载 | 驱动下载 | 游戏下载 | 源码下载 | 教程下载 | 站长在线 | 产品中心 | 报价中心
开发首页 | 开发语言 | .Net开发 | Java开发 | Web开发 | 数据库开发 | 移动开发 | 游戏开发 | 企业开发 | 操作系统 | 软件工程
VB VC Delphi PB BCB C++ - ASP.net C# VB.net - J2EE J2SE J2ME EJB - ASP PHP JSP CGI - MSSQL Oracle DB2 MySQL - CodingLife
  Java开发首页 | Java基础 | Java高级编程 | J2EE | J2SE | EJB | J2ME | Servlet/JSP | Applet/Swing | Struts/Hibernate
  您现在的位置:天新网 > 软件开发 > Java开发 > J2SE
谈谈J2SE中的序列化之接受默认序列化
http://dev.21tx.com 2005年02月05日 j2me开发网

每日文章精萃
.Net:ASPX页Web服务调用性能优化 Java:Enterprise JavaBeans导论(2)
ASP:一段加密函数 PHP:用PHP与XML联手进行网站编程
JSP:JSP高级编程(1) CGI:Perl直接入门详尽指南
VB:如何在VB中实现目录遍历 VC:VC下显示JPEG、GIF图像的简便方法

1 2 下一页

  首先要了解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

  如何保持向上兼容性:

  向上兼容性是指老的版本能够读取新的版本序列化的数据流。常常出现在我们的服务器的数据更新了,仍然希望老的客户端能够支持反序列化新的数据流,直到其更新到新的版本。可以说,这是半自动的事情。

  跟一般的讲,因为在java中serialVersionUID是唯一控制着能否反序列化成功的标志,只要这个值不一样,就无法反序列化成功。但只要这个值相同,无论如何都将反序列化,在这个过程中,对于向上兼容性,新数据流中的多余的内容将会被忽略;对于向下兼容性而言,旧的数据流中所包含的所有内容都将会被恢复,新版本的类中没有涉及到的部分将保持默认值。利用这一特性,可以说,只要我们认为的保持serialVersionUID不变,向上兼容性是自动实现的。

  当然,一但我们将新版本中的老的内容拿掉,情况就不同了,即使UID保持不变,会引发异常。正是因为这一点,我们要牢记一个类一旦实现了序列化又要保持向上下兼容性,就不可以随随便便的修改了!!!

  测试也证明了这一点,有兴趣的读者可以自己试一试。

上一篇: J2SE5.0新特性之ProcessBuilder
下一篇: J2SE5.0新特性之使用代理服务器

1 2 下一页

编辑推荐
相关内容
·JMX+J2SE5.0实现Web应用的安全管理
·用J2SE 5.0创建定制的泛型集合
·驯服Tiger(J2SE5.0)之集合框架
·用J2SE1.5建立多任务的Java应用程序
·谈谈J2SE中的序列化之接受默认序列化
·谈谈J2SE中的序列化之当序列化遭遇继承
·谈谈J2SE中的序列化之一个感性的认识
·J2SE5.0新特性之ProcessBuilder
·J2SE5.0新特性之使用代理服务器
·J2SE 1.5版本的新特性一览
·JMX+J2SE5.0实现Web应用的安全管理
·用J2SE 5.0创建定制的泛型集合
·驯服Tiger(J2SE5.0)之集合框架
·Java本纪之J2SE发展演变史
·历10年风雨——J2SE发展演变史
·驯服J2SE1.5之从 XML 中装载属性
·谈谈J2SE中的序列化之当序列化遭遇继承
·J2SE5.0新特性之ProcessBuilder
·J2SE1.5 注释语法新鲜试用
·J2SE 1.5版本的新特性一览
最近更新
人气最热
·谈谈J2SE中的序列化之当序列化遭遇继承
·谈谈J2SE中的序列化之一个感性的认识
·J2SE5.0新特性之ProcessBuilder
·J2SE5.0新特性之使用代理服务器
·J2SE1.5 注释语法新鲜试用
·J2SE 1.5版本的新特性一览
·J2SE 1.5版本的新特性一览
·J2SE1.5 注释语法新鲜试用
·谈谈J2SE中的序列化之当序列化遭遇继承
·谈谈J2SE中的序列化之一个感性的认识
·J2SE5.0新特性之ProcessBuilder
·J2SE5.0新特性之使用代理服务器

 
·[硬件]平民机箱 试用百盛冷静王38度机箱
·[数码]透视低端MP3做工 朗科迷你K320拆机
·[汽车]动感魅力--试驾奥迪全新S8运动豪华车
·[开发]真正的程序员用Pascal
·[资讯]Firefox与IE受黑客关注 铁幕神话遭到质
·[游戏]《天堂2》受恶意攻击 官方正在紧急维护
·[本本]笔记本电脑应该怎么样去维护?
·[办公]为求生存 倾销积压品 方正D737贱卖
·[手机]连续轰炸 西门子SL65终破2000元关口(图
·[考试]MCDBA--微软认证数据库系统管理员
·[学院]不得不学 装Win XP SP2前必做八件事
·[娱乐]魔力图书室
 

关于我们 | 联系我们 | 广告服务 | 工作机会 | 版权声明 | 欢迎投稿 | 网站地图
Copyright © 2000-2008 , www.21tx.com , All Rights Reserved .
© 晨新科技 版权所有 Created by TXSite.net