序列化 (serialization)
将对象的状态信息转换为可以存储或传输的窗体的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
序列化使其他代码可以查看或修改那些不序列化便无法访问的对象实例数据。确切地说,代码执行序列化需要特殊的权限:即指定了 SerializationFormatter 标志的 SecurityPermission。在默认策略下,通过 Internet 下载的代码或 Intranet 代码不会授予该权限;只有本地计算机上的代码才被授予该权限。
通常,对象实例的所有字段都会被序列化,这意味着数据会被表示为实例的序列化数据。这样,能够解释该格式的代码有可能能够确定这些数据的值,而不依赖于该成员的可访问性。类似地,反序列化从序列化的表示形式中提取数据,并直接设置对象状态,这也与可访问性规则无关。
对于任何可能包含重要的安全性数据的对象,如果可能,应该使该对象不可序列化。如果它必须为可序列化的,请尝试生成特定字段来保存不可序列化的重要数据。如果无法实现这一点,则应注意该数据会被公开给任何拥有序列化权限的代码,并确保不让任何恶意代码获得该权限。
序列化
序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
序列化的目的:
1、以某种存储形式使自定义对象持久化;
2、将对象从一个地方传递到另一个地方。
.NET Framework 提供两种序列化技术:
* 二进制序列化保持类型保真度,这对于在应用程序的不同调用之间保留对象的状态很有用。例如,通过将对象序列化到剪贴板,可在不同的应用程序之间共享对象。 您可以将对象序列化到流、磁盘、内存和网络等等。远程处理使用序列化“通过值”在计算机或应用程序域之间传递对象。
* XML 序列化仅序列化公共属性和字段,且不保持类型保真度。当您要提供或使用数据而不限制使用该数据的应用程序时,这一点是很有用的。由于 XML 是一个开放式标准,因此,对于通过 Web 共享数据而言,这是一个很好的选择。SOAP 同样是一个开放式标准,这使它也成为一个颇具吸引力的选择。
---------------------------------------------------------------------------------------------------------------------------------
对象的序列化:把java对象转换为字节序列的过程;ObjectOutputStream.writeObject(Object obj);
对象的反序列化:把字节序列转换为java对象的过程。ObjectInputStream.readObject();
只 有实现了Serializable或者Externalizable接口的对象才能被序列化。 ObjectOutputStream.writeObject(Object obj)否则会抛出 IOException;Externalizable继承Serializable,实现Externalizable接口的类完全由自身来控制来控制 序列化的行为,而仅实现Serializable的类可以采用默认的序列化方式。JDK中如:String类,包装类,Date类实现了 Serializable接口。
为了能读出正确的数据,必须保证向对象输出流写对象的顺序与从对象输入流读对象的顺序一致。
ObjectOutputStream按照默认方式序列化,仅仅对对象的非transient的实例变量进行序列化,而不会对对象的transient变量进行序列化,也不会序列化静态变量。
如果一个对象存在一对多的关联关系,那么都会序列化。
控制序列化的行为:
如果用户希望控制类的序列化,可以在序列化类中提供以下形式的writeObject()方法和readObject()方法;
private void writeObject(ObjectOutputStream out) throws IOException
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
采用自定义序列化方式的情况:
-
确保序列化的安全性,对敏感信息加密后再序列化,在反序列化的时候需要解密;
-
确保对象的成员变量符合正确的约束条件
-
优化序列化的性能。
-
便于更好的封装类的内部数据结构,确保类的接口不会被类的内部实现所束缚。
Externalizable:
Externalizable接口继承自Serializable接口,如果一个类实现了Externalizable接口,那么将完全由这个类控制自身的序列化行为,Externalizable接口声明了两个方法:
-
public void writeExternal(Objectoutput out)throws IOException ===序列化
-
public void readExternal(Objectinput in) throws IOException ClassNotFoundException ===反序列化 ,当在反序列化时,会先调用类的不带参数的构造方法,这是有别于默认反序列化方式的。
可序列化的不同版本的序列化兼容性:
凡是实现 Serializable接口的类都有一个表示序列化版本标识的静态常量,private static final longserialVersionUID; serialVersionUID的取值是java运行时环境根据类的内部细节自动生成的。如果对类的源码做了修改,再重新编译,新生成的类文件的 serialVersionUID的取值有可能会发生变化。
JDK 安装后,在它的bin目录下有一个serialver.exe 程序,用于查看实现了serializable接口的类的serialVersionUID。
序列化 的应用:
* 1. 永久性保存对象,保存对象的字节序列到本地文件中;
* 2. 通过序列化对象在网络中传递对象;
* 3. 通过序列化在进程间传递对象。