第二节:使类型可序列化

设计一个类型时,设计人员必须郑重地决定是否允许类型的实例序列化。类型默认是不可序列化的。例如,以下代码可能不会像你希望的那样工作:

internal struct Point { public Int32 x, y;}
private static void OptInSerialization()
        {
            Point pt = new Point { x = 1, y = 2 };
            using (var stream = new MemoryStream())
            {

                new BinaryFormatter().Serialize(stream, pt);//抛出 SerializationException
            }
        }

如果在你的程序中生成并运行上述代码,会发现格式化器的Serialize方法抛出一个异常。问题在于,Point类型的开发人员没有显示的指出Point对象可以序列化。为了解决这个问题,开发人员必须像下面这样向这个类型应用一个名为System.SerializableAttribute的定制的attribute。(注意,这个attribute是在System命名空间中定义的,而不是在System.Runtime.Serialization命名空间中定义的。)

[Serializable]
internal struct Point { public Int32 x, y;}

现在,如果重新生成运行应用程序并运行它,就会像预期那样工作,Point对象会顺利序列化到流中。序列化一个对象图时,格式化器会检查每个对象的类型都是可序列化的。如果对象图中的任何一个对象不可序列化,格式化器的Serialize方法都会抛出一个SerializationException异常。

注意:序列化一个对象图时,有的对象的类型也许能序列化,有的也许不能。考虑到性能,在序列化之前,格式化器不会验证对象图中的所有对象都能序列化。所以,序列化一个对象图时,在抛出SerializationException之前,完全有可能已经有一部分对象已经序列化到流中。如果发生这种情况,流中就会包含以损坏的数据。序列化一个对象时。如果你认为也许有一些对象不可序列化,那么写代码就应该能得体的从这些异常中恢复。一个方案是先将对象序列化到MemoryStream中。然后,如果所有对象都成功序列化,就可以将MemoryStream中的字节复制到你真正希望的目标流中(比如文件和网络)。

SerializableAttribute这个定制的attribute只能应用于引用类型(class)、值类型(struct)、枚举类型(enum)和委托(delegate)。注意,枚举和委托类型总是可序列化的,所以不必显示应用SerializableAttribute。除此之外,SerializableAttribute不会被派生继承。所以,给定以下两个类型定义,那么Person对象时可序列化的,而Employee对象时不可序列化的:

  [Serializable]  class Person { }
    internal class Employee : Person
    {
    }

为了解决这个问题,只要将SerializableAttribute应用于Employee类型:

[Serializable]
    internal class Person { }
    [Serializable]
    internal class Employee : Person
    {
    }

注意,上诉问题虽然很容易修正,但反之则不然。如果一个类型没有应用SerializableAttribute,那么很难想象如何从它派生出一个可序列化的类型。但这样设计时有原因的:如果基类不允许他的实例序列化,它的字段就不能序列化,因为基对象实际是派生对象的一部分。这正是为什么System.Object已经很体贴的应用了SerializableAttribute的原因。

注意:通常,建议你定义的大多数类型都设置成可序列化,毕竟,这能为类型的用户提供很大的灵活性。但是必须注意,序列化会读取一个对象的所有字段,不管这些字段声明为public,protected,internal还是private。如果一个类型的实例要包敏感和安全数据,或者数据在转移之后使没有含义或者没有值,就不应该使类型变的可序列化。

如果使用的一个类型不是为序列化而设计的,而且手上没有类型的源代码,无法从源代码添加序列化支持。在后面“反序列化对象时重写程序集和/类型”中,我会解释如何使任何不可序列化的类型变的可序列化。

时间: 2024-10-01 02:36:59

第二节:使类型可序列化的相关文章

第二节 Java Swing中的基本容器:JFrame

第二节 基本容器:JFrame 如果要使用Swing创建一个窗口,则直接使用JFrame即可,此类事Component类的子类,常用方法如下: 小试牛刀 创建一个简单的窗口 import java.awt.*; import java.io.*; import javax.swing.*; public class JavaSwingTest { public static void main(String args[]) throws IOException{ test1(); } //创建一

2014年度辛星css教程夏季版第二节

第一节我们简介了一下CSS的工作流程,我相信读者会有一个大体的认识,那么接下来我们将会深入的研究一下CSS的细节问题,这些问题的涉及将会使我们的工作更加完善. *************注释************ 1.CSS也是需要注释的,注释中的内容不会被解释执行,它也和C语言一样,用/*开头,用*/结尾,其中的内容会被当做注释,我们想怎么写就怎么写. 2.下面给个例子: p{ color: green; /* 我们在这里书写注释 * 辛星CSS,与博客园共同成长 */ font-size:

【软件构造】第二章第二节 软件构造的过程、系统和工具

第二章第二节 软件构造的过程.系统和工具 Outline 广义的软件构造过程 编程 静态代码分析 动态代码分析 调试与测试 重构 狭义的软件构造过程 构造系统:经典BUILD场景 构造系统的组件 构造过程和构造描述 Java编译工具 子目标和结构变体 构造工具 Notes ## 广义的软件构造过程 [编程(Coding)] 开发语言:如Java.C.Python 使用IDE(集成开发工具)的优势(组成) 方便编写代码和管理文件(有代码编辑器,代码重构工具.文件和库(Library)管理工具) 能

【软件构造】第三章第二节 设计规约

第三章第二节 软件规约 这一节我们转向关注"方法/函数/操作"是如何定义的,即讨论编程中的动词,规约. Outline 一个完整的方法 什么是设计规约,我们为什么需要他 行为等价性 规约的结构:前置条件与后置条件 规约的结构 可变方法的规约 规约的评价 规约的确定性 规约的陈述性 规约的强度 如何设计一个好的规约 是否使用前置条件 Notes ## 一个完整的方法 一个完整的方法包括规约spec和实现体implementation: "方法"是程序的积木,它可以被独

【软件构造】第五章第二节 设计可复用的软件

第五章第二节  设计可复用的软件 5-1节学习了可复用的层次.形态.表现:本节从类.API.框架三个层面学习如何设计可复用软件实体的具体技术. Outline 设计可复用的类--LSP 行为子结构 Liskov替换原则(LSP) 各种应用中的LSP 数组是协变的 泛型中的LSP 为了解决类型擦除的问题-----Wildcards(通配符) 设计可复用的类--委派与组合 设计可复用库与框架 Notes ## 设计可复用的类--LSP 在OOP之中设计可复用的类 封装和信息隐藏 继承和重写 多态.子

【软件构造】第六章第二节 可维护的设计模式

第六章第二节 可维护的设计模式 Outline 创造性模式:Creational patterns 工厂模式(Factory Pattern) 抽象工厂模式(Abstract Factory Pattern) 建造者模式(Builder Pattern) 结构化模式:Structural patterns 桥接模式(Bridge Pattern) 代理模式(Proxy Pattern) 组合模式(Composite Pattern) 行为化模式:Behavioral patterns 中介者模式

【软件构造】第七章第二节 错误与异常处理

第七章第二节 错误与异常处理 本节关注:Java中错误和异常处理的典 型技术--把原理落实到代码上! Outline: Java中的错误和异常(java.lang.throwable) 异常 Runtime异常与其他异常(Exception) Checked异常和unchecked异常 checked异常的处理机制 自定义异常 Notes: ## Java中的错误和异常 [Throwable] Java.lang.throwable Throwable 类是 Java 语言中所有错误或异常的超类

杨森翔:春节文化大观上编 第三章 春节古诗词 目录 第一节:春节诗词概述 一、 除夕诗词概述 二、元日诗词概述 三、 元宵诗词概述 第二节:春节古诗词拾萃

杨森翔:春节文化大观上编 第三章 春节古诗词 目录 第一节:春节诗词概述 一. 除夕诗词概述 二.元日诗词概述 三. 元宵诗词概述 第二节:春节古诗词拾萃 一.腊祭诗词 二.祭灶诗词 三.除夕诗词 四.元旦诗词 五.人日诗词 六.元宵诗词 第一节:春节古诗词概述 中国的春节,作为除旧迎新的节日,时间相当长,从年前的腊月二十三,天空中就似乎弥漫了节日的气息.这种节日的气氛,在保持传统风俗较好的地方,甚至会持续到二月二龙抬头的时候,但欢度春节的高潮,应该说是自除夕始一直到上元之夜.因此,历代歌咏和反

MFC第二节-网络编程

使用socket编程. 一.需要套接字库.要知道申请的套接字库的版本,版本号利用WORD类型表示:MAKEWORD,加载后要检查得到的是否是申请的版本. 二.需要创建套接字.套接字SOCKET结构体. 三.SOCKET对象和SOCKADDR套接字地址绑定,对TCP\IP编程中,可以用SOCKADDR_IN代替SOCKADDR(都是代表地址空间).SOCKADDR_IN包括sin_family:地址族,对于IP地址一直是AF_INET,sin_port是按网络字节顺序表示的端口地址,sin_add