Chinaunix首页 | 论坛 | 博客
  • 博客访问: 214337
  • 博文数量: 123
  • 博客积分: 3066
  • 博客等级: 中校
  • 技术积分: 1920
  • 用 户 组: 普通用户
  • 注册时间: 2007-08-23 21:22
文章分类

全部博文(123)

文章存档

2012年(1)

2010年(1)

2009年(48)

2008年(73)

我的朋友

分类: Java

2009-01-05 15:37:44

永久域名
2007-02-18

java串行化

Java中对象的串行化(Serialization)和transient关键字



一、串行化的概念和目的

1.什么是串行化

       对象的寿命通常随着生成该对象的程序的终止而终止。有时候,可能需要将对象的状态保存下来,在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将来再生的能力。叫作对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己 ,这个过程叫对象的串行化(Serialization-连续) 。串行化的主要任务是写出对象实例变量的数值。如果变量是另一对象的引用,则引用的对象也要串行化。这个过程是递归的,串行化可能要涉及一个复杂树结构的单行化,包括原有对象、对象的对象、对象的对象的对象等等。对象所有权的层次结构称为图表(graph)。

2.串行化的目的

Java对象的单行化的目标是为Java的运行环境提供一组特性,如下所示:

1) 尽量保持对象串行化的简单扼要 ,但要提供一种途径使其可根据开发者的要求进行扩展或定制。

2) 串行化机制应严格遵守Java的对象模型 。对象的串行化状态中应该存有所有的关于种类的安全特性的信息。

3) 对象的串行化机制应支持Java的对象持续性。

4) 对象的串行化机制应有足够的 可扩展能力以支持对象的远程方法调用(RMI)。

5) 对象串行化应允许对象定义自身 的格式即其自身的数据流表示形式,可外部化接口来完成这项功能。



二、串行化方法
从JDK1.1开始,Java语言提供了对象串行化机制 ,在java.io包中,接口Serialization用来作为实现对象串行化的工具 ,只有实现了Serialization的类的对象才可以被串行化。

Serializable接口中没有任何的方法。当一个类声明要实现Serializable接口时,只是表明该类参加串行化协议,而不需要实现任何特殊的方法。下面我们通过实例介绍如何对对象进行串行化。

1.定义一个可串行化对象

一个类,如果要使其对象可以被串行化,必须实现Serializable接口。我们定义一个类Student如下:
 class Student implements Serializable {

//1 首先定义了一个类Student,实现了Serializable接口

    int id;  

    String name; 

    int age; 

    transient String department; 

// Java语言的关键字[保留字],用来表示一个域不是该对象串行化的一部分。



    public Student(int id, String name, int age, String department) {

       this.id = id;

       this.name = name;

       this.age = age;

       this.department = department;

    }

}


2.构造对象的输入/输出流

要串行化一个对象,必须与一定的对象输出/输入流联系起来,通过对象输出流将对象状态保存下来,再通过对象输入流将对象状态恢复。

java.io包中,提供了ObjectInputStream和ObjectOutputStream将数据流功能扩展至可读写对象 。在ObjectInputStream 中用readObject()方法可以直接读取一个对象,ObjectOutputStream中用writeObject()方法可以直接将对象保存到输出流中。

package com.gwssi.study.pkg3;

import java.io.*;

public class ObjectSer {

    public static void main(String args[]) throws IOException,ClassNotFoundException{

       Student stu = new Student(101972040, "YaoMing", 27, "basketball");

       FileOutputStream fo = new FileOutputStream("data.ser");

       ObjectOutputStream so = new ObjectOutputStream(fo);

       try {

//2 通过对象输出流的writeObject()方法将Student对象保存到文件 data.ser中

      so.writeObject(stu);

           so.close();

       } catch (IOException e) {

           System.out.println(e);

       }

       stu = null;

      

      

       FileInputStream fi = new FileInputStream("data.ser");

       ObjectInputStream si = new ObjectInputStream(fi);

       try {

//3 通过对家输入流的readObjcet()方法从文件data.ser中读出保存的Student对象

           stu = (Student)si.readObject();

           si.close();

       } catch (IOException ex) {

           System.out.println(ex);

       }

      

       //4 从运行结果可以看到,通过串行化机制,可以正确地保存和恢复对象的状态

       System.out.println("Student Info:");

       System.out.println("ID:" + stu.id);

       System.out.println("Name:" + stu.name);

       System.out.println("Age:" + stu.age);

       System.out.println("Dep:" + stu.department);

    }

}
  运行结果如下:


Student Info:
ID:101972040
Name:YaoMing
Age:27
Dep:null



在这个例子中,

1首先定义了一个类Student,实现了Serializable接口

2通过对象输出流的writeObject()方法将Student对象保存到文件 data.ser中

3通过对家输入流的readObjcet()方法从文件data.ser中读出保存的Student对象

4从运行结果可以看到,通过串行化机制,可以正确地保存和恢复对象的状态










三、串行化的注意事项
1.串行化能保存的元素

串行化只能保存对象的非静态成员交量,不能保存任何的成员方法和静态的成员变量,而且串行化保存的只是变量的值,对于变量的任何修饰符都不能保存。

2.transient关键字

对于某些类型的对象,其状态是瞬时的,这样的对象是无法保存其状态的。例如一个Thread对象或一个FileInputStream对象 ,对于这些字段,我们必须用transient关键字标明,否则编译器将报措。

另外 ,串行化可能涉及将对象存放到 磁盘上或在网络上发达数据,这时候就会产生安全问题。因为数据位于Java运行环境之外,不在Java安全机制的控制之中。对于这些需要保密的字段,不应保存在永久介质中 ,或者不应简单地不加处理地保存下来 ,为了保证安全性。应该在这些字段前加上transient关键字。

  • 10:52
  • 浏览 (845)
  • 评论 (0)
  • 分类:
评论
发表评论
表情图标

字体颜色:  字体大小:  对齐:
提示:选择您需要装饰的文字, 按上列按钮即可添加上相应的标签

您还没有登录,请后发表评论

penghao122
搜索本博客
最近访客
博客分类
我的相册
72d391927f43d49f0f8036ec0862a4a4
我的留言簿 >>更多留言
  • 漂过
    -- by nivcheral
  • 请教一些关于WEB当中的ISession的存储和释放的一些规则,因为当我页面跳转 ...
    -- by xh850
  • 被迷住了
    -- by fcm915
最近加入圈子
存档
最新评论
  • Rss
  • Rss_google
  • Rss_zhuaxia
  • Rss_xianguo

什么叫做对象的串行化?

libad()2002-06-06 18:54:46 在 Java / J2SE / 基础类 提问

什么叫做对象的串行化? 问题点数:0、回复次数:7

a_ja(青藏牦牛)回复于 2002-06-06 19:10:07 得分 0

不知道,我就知道对象的序列化

hccpro(hcc)回复于 2002-06-06 19:20:00 得分 0

串行化和序列化是一个道理。  
   
  就是把对象保存在永久存储器上的方法。

killjoy(伪装者)回复于 2002-06-06 19:34:17 得分 0

对象的串型化,也有叫做对象的序列话,并不只是简单的把对象保存在存储器上,它可以使我们在流中传输对象,使对象变的可以像基本数据一样传递。  
  RMI的实现也是基于对象序列化的。

bonniekevon(Bonnie Kevon)回复于 2002-06-06 22:18:15 得分 0

对象的序列化,是指让对象实现可序列化接口,使对象能够在流中传输.  
  将对象储存在存储器上只不过是对对象序列化的一个应用结果.

hehecafe(我喜欢从高处跳下来的感觉)回复于 2002-06-07 00:58:35 得分 0

实现了序列化的类,可以将该类的对象的当前状态保存下来,以后可以直接的使用上次保存的对象。但是有很多东西我都不是很明白,希望能有一个高手来指点一下!看书!!

goatzx(天天)回复于 2002-06-07 10:03:41 得分 0

在RMI分布式应用系统中,服务器与客户机之间传递的Java对象必须是可序列化的对象。不可序列化的对象不能在对象流中进行传递。对象序列化扩展了核心Java输入/输出类,同时也支持对象。对象序列化支持把对象编码以及将通过它们可访问到的对象编码变成字节流;同时,它也支持流中对象图形的互补重构造。序列化用于轻型持久性和借助于套接字或远程方法调用(RMI)进行的通信。序列化中现在包括一个   API(Application   Programming   Interface,应用程序接口),允许独立于类的域指定对象的序列化数据,并允许使用现有协议将序列化数据域写入流中或从流中读取,以确保与缺省读写机制的兼容性。  
   
  为编写应用程序,除多数瞬态应用程序外,都必须具备存储和检索   Java对象的能力。以序列化方式存储和检索对象的关键在于提供重新构造该对象所需的足够对象状态。存储到流的对象可能会支持   Serializable(可序列化)或   Externalizable(可外部化)接口。对于Java对象,序列化形式必须能标识和校验存储其内容的对象所属的   Java类,并且将该内容还原为新的实例。对于可序列化对象,流将提供足够的信息将流的域还原为类的兼容版本。对于可外部化对象,类将全权负责其内容的外部格式。序列化   Java   对象的目的是:提供一种简单但可扩充的机制,以序列化方式维护   Java对象的类型及安全属性;具有支持编组和解编的扩展能力以满足远程对象的需要;具有可扩展性以支持   Java   对象的简单持久性;只有在自定义时,才需对每个类提供序列化自实现;允许对象定义其外部格式。  
   
 

mty(天鱼)回复于 2002-06-07 12:12:57 得分 0

对象的序列化其实也只是让此对象实现一个空的接口而已..接口Serialize是个空接口,没有任何方法声明.大家如果用过instanceof的话,就会对这个结构的作用有一定了解的.

相关问题

  • 发表于 2002-6-19 09:54 
    java串行化的问题,高手来挑战自己?

    现在有一个Image,但是我们知道Image没有实现串行化,为了在b/s结构中b能从s得到该image,自己创建一个实现了串行化的类,里面封装image,但是这样我还是不能在b端得到该image

    我也想到用数据流的方法,如果用隧道技术该如何实现?

    向高手请教有什么好的方法?让我顺利的用applet从servlet得到该image
    摆脱


    __________________
    ......
    只看该作者    顶部
    离线 zw_java
    中级会员



    精华贴数 0
    个人空间 0
    技术积分 574 (3485)
    社区积分 7 (13109)
    注册日期 2001-10-15
    论坛徽章:1
    授权会员          
               

    发表于 2002-6-20 09:01 
    那个榜榜手呀!

    1


    __________________
    ......
    只看该作者    顶部
    离线 greenflute


    精华贴数 0
    个人空间 0
    技术积分 7339 (187)
    社区积分 170 (2704)
    注册日期 2001-10-26
    论坛徽章:17
    现任管理团队成员 ITPUB元老 管理团队2007贡献徽章 会员2007贡献徽章 2009新春纪念徽章 2008北京奥运纪念徽章:沙滩排球
    2008新春纪念徽章          

    发表于 2002-6-20 10:40 
    使用一个单独的Servlet对外以数据流形式提供Image

    使用一个单独的Servlet对外以数据流形式提供Image,然后在Applet中使用URL Connection来获取数据。
阅读(2445) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~