文档章节

序列化,反序列化实例

china008
 china008
发布于 2014/10/11 10:23
字数 1113
阅读 153
收藏 6

public class foo implements Serializable{
    private int width;
    private int height;
    public int getWidth() {
        return width;
    }
    public void setWidth(int width) {
        this.width = width;
    }
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }
    
}


public class test_serialize extends TestCase {

//序列化,fileoutputstream 存储路径文件,如果是相对路径,那么存储在项目根目录下,如果是绝对路径,存储在绝对路径下面
    public void tests() throws IOException{
        foo a = new foo();
        a.setHeight(200);
        a.setWidth(300);
        foo b = new foo();
        b.setHeight(300);
        b.setWidth(400);
        try{
        FileOutputStream fs=new FileOutputStream("d:/foo.ser");
        ObjectOutputStream os = new ObjectOutputStream(fs);
        os.writeObject(a);
        os.writeObject(b);
        os.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }

//反序列化
    public void testgets() throws IOException, ClassNotFoundException{
        try {
            FileInputStream fs = new FileInputStream("d:/foo.ser");
            ObjectInputStream ois = new ObjectInputStream(fs);
            foo a=(foo)ois.readObject();
            foo b=(foo)ois.readObject();
            System.out.println(a.getHeight());
            System.out.println(b.getHeight());
            
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}



相关注意事项
    a)序列化时,只对对象的状态进行保存,而不管对象的方法;
    b)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
    c)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
    d)并非所有的对象都可以序列化,,至于为什么不可以,有很多原因了,比如:
        1.安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行rmi传输  等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的。
       2. 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分  配,而且,也是没有必要这样实现。 


默认的 serialization 对 类的结构有要求,一般将来版本升级了导致服务端和客户版本不一样,或者你用新版本读取一个以前旧版本写入磁盘的序列化的对象的话,需要这两个版本是兼容 的,达到这个要求至少包括下面这个字段,并且新旧两个版本的类中它的值应该是一样的,其它特殊情况规范也有办法做到,比如你的结构变了,以前 name / phone 都是 A 的字段,后来新版本创建了一个内部类叫 Contact name phone
并到这两个字段移到内部类 Contact 中去了的话,Java 也有办法在新版本中提供自定义 readObject/writeObject 这个过程来确保兼容旧版本。

private static final long serialVersionUID; //
在一个类的多个版本中要相同的值,对于不它的类中,它们的值不要求唯一。
http://java.sun.com/developer/technicalArticles/Programming/serialization/
 

serialVersionUID作用:序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。 有两种生成方式: 一个是默认的1L,比如:private static final long se...

serialVersionUID作用:
序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。

有两种生成方式:

一个是默认的1L,比如:
private static final long serialVersionUID = 1L;
一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如:

 
private static final long serialVersionUID = xxxxL;
当你一个类实现了Serializable接口,如果没有定义serialVersionUIDEclipse会提供这个

提示功能告诉你去定义 。在Eclipse中点击类中warning的图标一下,Eclipse就会

自动给定两种生成的方式。如果不想定义它,在Eclipse的设置中也

可以把它关掉的,设置如下:

 
Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==>
Potential programming problems
Serializable class without serialVersionUIDwarning改成ignore即可。

如果你没有考虑到兼容性问题时,就把它关掉,不过有这个功能是好的,只要任何类别实现了Serializable这个接口的话,如果没有加入serialVersionUIDEclipse都会给你warning提示,这个serialVersionUID为了让该类别Serializable向后兼容。

如果你的类Serialized存到硬盘上面后,可是后来你却更改了类别的field(增加或减少或改名),当你Deserialize时,就会出现Exception的,这样就会造成不兼容性的问题。

但当serialVersionUID相同时,它就会将不一样的fieldtype的预设值Deserialize,可避开不兼容性问题。


© 著作权归作者所有

china008
粉丝 6
博文 286
码字总数 30406
作品 0
海淀
私信 提问
加载中

评论(1)

叶秀兰
叶秀兰
标题打错了:)
Java序列化

什么是序列化 所谓的序列化,即把java对象以二进制形式保存到内存、文件或者进行网络传输。从二进制的形式恢复成为java对象,即反序列化。 通过序列化可以将对象持久化,或者从一个地方传输到...

德彪
2017/11/25
0
0
Effective Java 第三版—— 90. 考虑序列化代理替代序列化实例

Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所以JDK 最好下载 JDK 9以上的版本。 90. 考虑序列化代...

M104
04/04
0
0
【10】Effective Java - 序列化

1、谨慎地实现Serializable接口 (1)序列化和反序列化 将一个对象编码成一个字节流,称为序列化(serializing);相反的处理过程,称之为反序列化(deserializing) (2)实现Serializable接...

xixicat
2014/07/14
104
0
在Java中如何使用transient

Java语言的transient不像class、synchronized和其他熟悉的关键字那样众所周知,因而它会出现在一些面试题中。这篇文章我将为大家讲解transient。 transient的用途 Q:transient关键字能实现什...

dannyhe
2015/11/16
60
0
通过 JSON-B 自定义绑定

JSON Binding API 入门,第 2 部分 通过 JSON-B 自定义绑定 通过和注解运行时配置来自定义 JSON 绑定 Alex Theedom 2017 年 12 月 14 日发布 系列内容: 此内容是该系列 2 部分中的第 # 部分...

Alex Theedom
2017/12/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周五乱弹 —— 匹诺曹也是韩国人

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @watergood :分享海先生的单曲《烟花巷》 《烟花巷》- 海先生 手机党少年们想听歌,请使劲儿戳(这里) @Cyber-Pan :已经很久没有十点前下过...

小小编辑
今天
7
1
Snack3 之 Jsonpath使用

Snack3 之 Jsonpath使用 一、 Snack3 和 JSONPath 介绍 Snack3 是一个支持JSONPath的JSON框架。JSONPath是一个很强大的功能,也可以在Java框架中当作对象查询语言(OQL)来使用。 <dependenc...

刘之西东
今天
4
0
7. 彤哥说netty系列之Java NIO核心组件之Selector

<p align="right">——日拱一卒,不期而至!</p> 你好,我是彤哥,本篇是netty系列的第七篇。 简介 上一章我们一起学习了Java NIO的核心组件Buffer,它通常跟Channel一起使用,但是它们在网络...

彤哥读源码
昨天
21
0
在Jupyter notebooks 中运行GRASS GIS

在Ubuntu16.04中,首先安装jupyter: python3 -m pip install --upgrade pippython3 -m pip install jupyter 然后创建一个sh脚本: # directory where GRASS GIS lives# GRASS GIS 的安装......

ddd口木呆
昨天
4
0
c++ get() getline()读取行

天王盖地虎626
昨天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部