转自:http://blog.csdn.net/chx10051413/article/details/40784667

http://www.cnblogs.com/baoendemao/p/3804797.html

Java 中如何序列化一个对象

我们都知道java 中无法保存一个对象到文本文件中,但是当我们有这种需求的时候,我们可以通过java 的序列化功能把当前对象的一些属性以二进制的形式保存到文件中。当我们需要这个对象的时,只需要从二进制文件中还原为保存前的对象即可。从这里我们可以得到启发,如果想把机器A 上的一个Student 对象发送到机器B 上,我们可以把Student 对象序列化成二进制,然后把该二进制发送给机器B,机器B 就可以根据二进制数据还原成Student 对象了,这就变相的实现了在机器间传播对象的功能。

写入序列化数据到文件中,主要是两个对象,一个对象是FileOutputStream 对象,一个是ObjectOutputStream 对象,ObjectOutputStream 负责向指定的流中写入序列化的对象。当从文件中读取序列化数据时,主要需要两个对象,一个是FileInputStream ,一个是ObjectInputStream 对象,ObjectInputStream 负责从指定流中读取序列化数据并还原成序列化前得对象。另外,序列化的读取数据与写入的顺序相同,比如我们序列化时先写入数据A ,再写入B ,最后写入C ;那么我们再读取数据的时候,读取到的第一个数据为A ,读取到的第二个数据为B ,最后读取到的数据为C ,即:先写入先读取的原则。

在序列化一个对象的时候,这个对象必须实现java.io.Serializable 接口, Serializable 接口中不含任何方法,这个可以理解为声明该对象是可以序列化的方法吧。当我们在序列化一个对象时,有些属性我们不想序列化(可以减少数据量),那么我们可以声明该属性为瞬间态(用transient 关键字声明)。另外,静态字段也是不会被序列化的。

当我们在序列化一个对象时,如果该对象没有覆写writeObject 或者readObject 方法,那么系统将采用默认的方法进行序列化,如果序列化对象中有这两个方法,则采用对象中的这两个方法进行序列化。至于如何找到的这两个方法,通过代码我们可以跟踪到是根据反射的方式进行判断对象是否覆写这两个方法。另外,这两个方法在对象中是

我们所说的流,都是针对内存说的,比如为什么打印到屏幕上就是System.out.println();而从屏幕等待用户输入的却是System.in呢?因为对于内存来说,把字符串打印到屏幕上是从内存流向屏幕这个显示器的,也就是输出,而从屏幕等待用户输入呢?就是等待键盘将字符输入到内存中。

所以,你根本就不用死记硬背,当你遇到IO的时候,就想两件事,第一,我的内存是中心,第二看看流的方向(矢量)!

好吧,那么往硬盘上写文件是out还是in呢?别一看到“写”文件你就说in,那是望文生义,你看,写文件的流向,是 内存---------->硬盘 内存为中心,到硬盘,OK 用out 那么就是FileOutputStream、BufferedOutputStream 等等
那读文件呢?是 内存<---------------硬盘 那么就是in了 , 看清楚数据的流向就OK!

那我访问网络,看网页是什么呢 网络--------------->内存 是in 因为我们访问页面是要抓取该页面得一个html文件,那我要是在网络上输入帐号密码登陆呢? 是不是内存的东西要写到该服务器上呢,所以当然是out了!

同样socket编程用到更多的IO,这里分别用Server(服务器端)和Client(客户端)来说明

Server: 遇到请求,网络----->内存 IN                                            服务器应答, 内存------->网络 OUT
----------------------------------------------------------------------------------------------
Client: 请求服务, 内存----->网络 OUT                                        服务器应答, 网络------->内存 IN

被搞糊涂了?那么你先别想太多,只是想是内存的数据出去了就是out 外设的东西到内存了就IN了

Java 串行化技术可以使你将一个对象的状态写入一个Byte 流里,并且可以从其它地方把该Byte 流里的数据读出来,重新构造一个相同的对象。这种机制允许你将对象通过网络进行传播,并可以随时把对象持久化到数据库、文件等系统里。Java的串行化机制是RMI、EJB等技术的技术基础。用途:利用对象的串行化实现保存应用程序的当前工作状态,下次再启动的时候将自动地恢复到上次执行的状态。

序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。

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

2、串行化的特点:

(1)如果某个类能够被串行化,其子类也可以被串行化。如果该类有父类,则分两种情况来考虑,如果该父类已经实现了可串行化接口。则其父类的相应字段及属性的处理和该类相同;如果该类的父类没有实现可串行化接口,则该类的父类所有的字段属性将不会串行化。

(2)声明为static和transient类型的成员数据不能被串行化。因为static代表类的状态, transient代表对象的临时数据;

(3)相关的类和接口:在java.io包中提供的涉及对象的串行化的类与接口有ObjectOutput接口、ObjectOutputStream类、ObjectInput接口、ObjectInputStream类。

(1)ObjectOutput接口:它继承DataOutput接口并且支持对象的串行化,其内的writeObject()方法实现存储一个对象。ObjectInput接口:它继承DataInput接口并且支持对象的串行化,其内的readObject()方法实现读取一个对象。

(2)ObjectOutputStream类:它继承OutputStream类并且实现ObjectOutput接口。利用该类来实现将对象存储(调用ObjectOutput接口中的writeObject()方法)。ObjectInputStream类:它继承InputStream类并且实现ObjectInput接口。利用该类来实现读取一个对象(调用ObjectInput接口中的readObject()方法)。

对于父类的处理,如果父类没有实现串行化接口,则其必须有默认的构造函数(即没有参数的构造函数)。否则编译的时候就会报错。在反串行化的时候,默认构造函数会被调用。但是若把父类标记为可以串行化,则在反串行化的时候,其默认构造函数不会被调用。这是为什么呢?这是因为Java 对串行化的对象进行反串行化的时候,直接从流里获取其对象数据来生成一个对象实例,而不是通过其构造函数来完成。

import java.io.*;

public class Cat implements Serializable {

private String name;

public Cat () {

this.name = "new cat";

}

public String getName() {

return this.name;

}

public void setName(String name) {

this.name = name;

}

public static void main(String[] args) {

Cat cat = new Cat();

try {

FileOutputStream获得一个文件流,ObjectOutputStream链接对象和文件流,通过writeObject方法把对象写到硬盘上面,从内存中的对象写到硬盘,故是OUT流

FileOutputStream fos = new FileOutputStream("catDemo.out");

ObjectOutputStream oos = new ObjectOutputStream(fos);

System.out.println(" 1> " + cat.getName());

cat.setName("My Cat");

oos.writeObject(cat);

oos.close();

} catch (Exception ex) {  ex.printStackTrace();   }

try {

把硬盘文件中的对象写到内存,故是IN流

FileInputStream fis = new FileInputStream("catDemo.out");

ObjectInputStream ois = new ObjectInputStream(fis);

cat = (Cat) ois.readObject();

System.out.println(" 2> " + cat.getName());

ois.close();

} catch (Exception ex) {

ex.printStackTrace();

}

}

}//writeObject和readObject本身就是线程安全的,传输过程中是不允许被并发访问的。所以对象能一个一个接连不断的传过来

最后再给出一个连接:http://blog.csdn.net/lulei1217/article/details/50527824   关于lo的文章,以后备用

Java中如何序列化一个对象(转)的更多相关文章

  1. 简单聊聊java中如何判定一个对象可回收

    背景 说到java的特性,其中一个最重要的特性便是java通过new在堆中分配给对象的内存,不需要程序员主动去释放,而是由java虚拟机自动的回收.这也是java和C++的主要区别之一:那么虚拟机是如 ...

  2. Java中的序列化Serialable

    Java中的序列化Serialable https://blog.csdn.net/caomiao2006/article/details/51588838

  3. Java中的序列化与反序列化

    序列化定义 将对象转换为字节流保存起来,并在以后还原这个对象,这种机制叫做对象序列化. 将一个对象保存到永久存储设备上称为持久化. 一个对象要想能够实现序列化,必须实现java.io.Serializ ...

  4. 在Java中进行序列化和反序列化

    对象序列化的目标是将对象保存在磁盘中,或者允许在网络中直接传输对象. 对象序列化允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久保存在磁盘上或者通过网络将这种二进制流传输 ...

  5. java中的序列化

    遇到这个 Java Serializable 序列化这个接口,我们可能会有如下的问题 a,什么叫序列化和反序列化b,作用.为啥要实现这个 Serializable 接口,也就是为啥要序列化c,seri ...

  6. java中的序列化问题

    序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化,将数据分解成字节流,以便存储在文件中或在网络上传输.可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间.序列化是 ...

  7. java中的序列化与反序列化,还包括将多个对象序列化到一个文件中

    package Serialize; /** * Created by hu on 2015/11/7. */ //实现序列化必须实现的接口,这就是一个空接口,起到标识的作用 import java. ...

  8. 如何使用Externalizable接口自定义Java中的序列化

    Java序列化过程的缺点 我们都知道如何使用Serializable接口序列化/反序列化一个对象,并且如何使用writeObject 和readObject方法自定义序列化过程. 但是这些自定义还不够 ...

  9. java中的序列化和反序列化学习笔记

    须要序列化的Person类: package cn.itcast_07; import java.io.Serializable; /* * NotSerializableException:未序列化 ...

随机推荐

  1. HTML中元素 标签 属性

    HTNL中元素是以开始标签开始 结束标签结尾的 如:<p>this is a paragraph </p> <p>是开始标签   </p>是结束标签  ...

  2. JS中的原始类型和判断方法

    ECMAScript 中定义了 7 种原始类型: Boolean String Number Null Undefined Symbol(新定义) BigInt(新定义) 注意: 原始类型不包含 Ob ...

  3. 十七 Spring的JDBC模版:使用开源连接池,DBCP,C3P0

    DBCP的配置以及使用 引入jar包

  4. js去后台传递的值

    function test(){ var param = [[${list}]];//以集合为例 } 如果list里面是实体类那么就需要重写toString,或者转为json

  5. 数据库事务ACID特效

    一.数据库事务正确执行的4个基础要素: 1.原子性 整个事务中的所有操作,要么全部完成,要么全部不完成,不可能停滞在中间某个环节.事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状 ...

  6. 新闻网大数据实时分析可视化系统项目——2、linux环境准备与设置

    1.Linux系统常规设置 1)设置ip地址 使用界面修改ip比较方便,如果Linux没有安装操作界面,需要使用命令:vi /etc/sysconfig/network-scripts/ifcfg-e ...

  7. springboot打包的问题可执行jar和不可执行jar

    具体解释可以参看:https://www.cnblogs.com/liaojie970/p/9007577.html 如果只是想要依赖那么可以将springboot自带的打包插件换掉就可以了,换为如下 ...

  8. WebApi如何接收前台传递过来的数组

    var ids = ["111", "222", "333"];$.ajax({ url: host + '/User/deleteByID ...

  9. osgb的顶点,纹理,索引,UV读取与存储

    virtual void apply(osg::Geode& node) { ; i < node.getNumDrawables(); i++) { osg::Geometry* ge ...

  10. Vue中 onmouseenter,onmouseleave,onmouseover,onmouseout的区别

    今天在学Vue视频的时候,提到了这四个触发事件,我就想做下笔记: 1.onmouseenter和onmouseleave是一组:当鼠标进入指定区域的时候触发,但是不支持冒泡,进入或者离开子组件都不触发 ...