`
tenn
  • 浏览: 565305 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
文章分类
社区版块
存档分类
最新评论

为什么JAVA要实现对象序列化

阅读更多

简单来说序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,流的概念这里不用多说(就是I/O),我们可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间(注:要想将对象传输于网络必须进行流化)!在对对象流进行读写操作时会引发一些问题,而序列化机制正是用来解决这些问题的!
如上所述,读写对象会有什么问题呢?比如:我要将对象写入一个磁盘文件而后再将其读出来会有什么问题吗?别急,其中一个最大的问题就是对象引用!举个例子来说:假如我有两个类,分别是A和B,B类中含有一个指向A类对象的引用,现在我们对两个类进行实例化{ A a = new A(); B b = new B(); },这时在内存中实际上分配了两个空间,一个存储对象a,一个存储对象b,接下来我们想将它们写入到磁盘的一个文件中去,就在写入文件时出现了问题!因为对象b包含对对象a的引用,所以系统会自动的将a的数据复制一份到b中,这样的话当我们从文件中恢复对象时(也就是重新加载到内存中)时,内存分配了三个空间,而对象a同时在内存中存在两份,想一想后果吧,如果我想修改对象a的数据的话,那不是还要搜索它的每一份拷贝来达到对象数据的一致性,这不是我们所希望的!
    以下序列化机制的解决方案:

    1.保存到磁盘的所有对象都获得一个序列号(1, 2, 3等等)

    2.当要保存一个对象时,先检查该对象是否被保存了。

    3.如果以前保存过,只需写入"与已经保存的具有序列号x的对象相同"的标记,否则,保存该对象

    通过以上的步骤序列化机制解决了对象引用的问题!

    序列化的实现

    将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,然后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就可以将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。

修改默认的序列化机制

在序列化的过程中,有些数据字段我们不想将其序列化,对于此类字段我们只需要在定义时给它加上transient关键字即可,对于transient字段序列化机制会跳过不会将其写入文件,当然也不可被恢复。但有时我们想将某一字段序列化,但它在SDK中的定义却是不可序列化的类型,这样的话我们也必须把他标注为transient,可是不能写入又怎么恢复呢?好在序列化机制为包含这种特殊问题的类提供了如下的方法定义:

private void readObject(ObjectInputStream in) throws

IOException, ClassNotFoundException;

private void writeObject(ObjectOutputStream out) throws

IOException;

(注:这些方法定义时必须是私有的,因为不需要你显示调用,序列化机制会自动调用的)

使用以上方法我们可以手动对那些你又想序列化又不可以被序列化的数据字段进行写出和读入操作。

下面是一个典型的例子,java.awt.geom包中的Point2D.Double类就是不可序列化的,因为该类没有实现Serializable接口,在我的例子中将把它当作LabeledPoint类中的一个数据字段,并演示如何将其序列化!
import java.io.*;
import java.awt.geom.*;
public class TransientTest
{
public static void main(String[] args)
{
LabeledPoint label = new LabeledPoint("Book", 5.00, 5.00);
try
{
System.out.println(label);//写入前
ObjectOutputStream out = new ObjectOutputStream(new
FileOutputStream("Label.txt"));
out.writeObject(label);
out.close();

System.out.println(label);//写入后

ObjectInputStream in = new ObjectInputStream(new
FileInputStream("Label.txt"));
LabeledPoint label1 = (LabeledPoint)in.readObject();
in.close();
System.out.println(label1);//读出并加1.0后
}
catch (Exception e)
{
e.printStackTrace();
}
}

}
class LabeledPoint implements Serializable
{
public LabeledPoint(String str, double x, double y)
{
label = str;
point = new Point2D.Double(x, y);
}

private void writeObject(ObjectOutputStream out) throws IOException
{
/**
*必须通过调用defaultWriteObject()方法来写入
*对象的描述以及那些可以被序列化的字段
*/
out.defaultWriteObject();
out.writeDouble(point.getX());
out.writeDouble(point.getY());
}

private void readObject(ObjectInputStream in)
throws IOException, ClassNotFoundException
{
/**
*必须调用defaultReadObject()方法
*/
in.defaultReadObject();
double x = in.readDouble() + 1.0;
double y = in.readDouble() + 1.0;
point = new Point2D.Double(x, y);
}

public String toString()
{
return getClass().getName()
+ "[label = "+ label
+ ", point.getX() = "+ point.getX()
+ ", point.getY() = "+ point.getY()
+ "]";
}

private  String label;
transient private Point2D.Double point;
}

分享到:
评论
1 楼 shuaiji 2011-10-09  

相关推荐

    什么是Java的序列化和反序列化?如何实现对象的序列化和反序列化?(java面试题附答案).txt

    通过实现 Serializable 接口,Java对象可以被序列化和反序列化。序列化可以将对象转换为字节流,以便于存储或传输。反序列化则可以将字节流重新转换为原始对象。需要注意的是,序列化和反序列化的类必须具有相同的 ...

    Java 对象序列化详解以及实例实现和源码下载

    Java中的序列化机制有两种实现方式: 一种是实现Serializable接口 另一种是实现Externalizable接口 区别: 实现Serializable接口 1 系统自动储存必要的信息 2 Java内建支持,易于实现,只需实现该接口即可,无须任何...

    深入探索Java对象的序列化

    Serializable有一个子接口Externalizable,实现Externalizable接口的类可以自行控制对象序列化荷反序列化过程。 一般来说,没有必要自己实现序列化接口,直接交给Java虚拟机是上策。 实现了序列化接口的类,如果...

    对象序列化 串行化

    对象序列化 串行化 实现java对象的保存

    Java对象序列化使用基础

    所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象。这个过程也可以通过...像RMI、Socket、JMS、EJB它们中的一种,彼此为什么能够传递Java对象,当然都是对象序列化机制的功劳。

    Java中对象序列化与反序列化详解

    主要介绍了Java中对象序列化与反序列化,较为详细的分析了java中对象序列化的概念、原理、实现方法及相关注意事项,具有一定参考借鉴价值,需要的朋友可以参考下

    java序列化反序列化

    java序列化反序列化 可以将一个对象保存起来哦,哈哈,很实用,别忘了实现序列化接口

    深入分析Java的序列化与反序列化

     为什么实现了java.io.Serializable接口才能被序列化  transient的作用是什么  怎么自定义序列化策略  自定义的序列化策略是如何被调用的  ArrayList对序列化的实现有什么好处  Java对象的序列化  ...

    XStream <--> Java 对象序列化为 XML 互换

    使用 XStream 不用任何映射就能实现多数 Java 对象的序列化。在生成的 XML 中对象名变成了元素名,类中的字符串组成了 XML 中的元素内容。使用 XStream 序列化的类不需要实现 Serializable 接口。XStream 是一种序列...

    Java高级程序设计实战教程第五章-Java序列化机制.pptx

    对象序列化是Java编程中的必备武器 Java高级程序设计实战教程第五章-Java序列化机制全文共15页,当前为第4页。 5.2.2 序列化应用 当你想把内存中的对象状态保存到一个文件中或者数据库中时候; 当你想用套接字在...

    java对象实现序列化

    NULL 博文链接:https://nicegege.iteye.com/blog/2206498

    java序列化和反序列化,面试必备

    意义:序列化机制允许将实现序列化的Java对象转换为字节序列,并将字节序列保存在磁盘中,或通过网络传输,以达到以后恢复成原来的对象。序列化机制使地对象可以脱离程序的运行而独立存在。 使用场景:所有在网络上...

    影院管理系统(序列化)

    影院管理系统!主要包含了反射和序列化等知识的应用,对对象的序列化

    java中对象的序列化与反序列化深入讲解

    主要给大家介绍了关于java中对象的序列化与反序列化的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

    java序列化

    Java平台允许我们在内存中创建可复用的Java对象,但一般情况下,只有当JVM(Java Virtual Machine(Java虚拟机))处于运行时,这些对象才可能存在(即,这些对象的生命...Java对象序列化就能够帮助我们实现该功能。

    Java序列化与反序列化三种格式存取

     一般而言,要使得一个类可以序列化,只需简单实现java.io.Serializable接口即可(还要实现无参数的构造方法)。该接口是一个标记式接口,它本身不包含任何内容,实现了该接口则表示这个类准备支持序列化的功能。...

    使用Java序列化实现一个简单的文件备份工具.txt

    这段代码实现了一个简单的文件备份工具FileBackupTool,其中使用了Java的序列化机制。在类的构造方法中,首先接收两个参数:源文件路径和备份文件路径。然后实现了一个backup()方法,用于将源文件进行备份。在该方法...

    java序列化深度探讨

    对象序列化就是把对象写入到输出流中,用来存储或者传输。 对象的反序列化就是从输入流中读取对象。 要序列化的对象应该实现Serializable接口。 Serializable接口是一个标识接口,没有抽象方法。

    Java-使用序列化保存对象数据到文件学习总结

    Java当中提供了一种序列化操作的方式,用一个字节序列来表示一个对象,该字节序列中保存了对象的属性、对象的数据、对象的类型。把字节序列化保存到文件中,就可以做到持久化保存数据内容。 1.2 如何将对象数据序列...

    GSON实现Java对象的JSON序列化与反序列化的实例教程

    GSON是Google开发并开源的一个Java的JSON转换库,这里我们将来讲解GSON实现Java对象的JSON序列化与反序列化的实例教程,需要的朋友可以参考下

Global site tag (gtag.js) - Google Analytics