序列化
序列化 (Serialization)是将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。
序列化使其他代码可以查看或修改,那些不序列化便无法访问的对象实例数据。确切地说,代码执行序列化需要特殊的权限:即指定了 SerializationFormatter 标志的 SecurityPermission。在默认策略下,通过 Internet 下载的代码或 Internet 代码不会授予该权限;只有本地计算机上的代码才被授予该权限。
编程应用
1、依靠Serializable接口进行声明,如果需要特殊操作可以实现Externalizable接口。Serializable接口属于旗标接口【标识接口】,仅仅只起到说明的作用,没有需要实现的方法。
public interface Serializable { }
2、可以通过ObjectInputStream和ObjectOutputStream提供的方法直接读写对象通过序列化将一个对象持久化存储到文件中。
注意:通过序列化写出对象,在通过反序列化读取对象的过程中,一般要求不允许修改类定义,否则InvalidClassException
编程细节
1.接口问题:需要通过对象流读写的对象必须实现序列化接口,否则NotSerializableException
2.特殊接口:Serializable接口属于标识接口,没有需要实现的方法,所有的序列化和反序列化操作都是由虚拟机负责实现。Externalizable接口定义,可以支持用户自定义实现序列化的细节操作,除非特殊需求一般不使用Externalizable接口,因为没有必要自定义。
3.类型转换:通过反序列化获取的对象是Object类型,如果调用对象中特殊的方法则必须先进行窄化操作。
4.序列号问题:Eclipse中针对实现了序列化接口的类定义会有这样一个警告信息,要求提供一个序列号serialiVersionUID。
5.特殊关键字:一般针对敏感数据不应该进行序列化操作,例如当前账户的口令属性。针对不需要进行序列化操作的属性可以添加一个关键字transient,表示该属性不参与序列化和反序列化操作。
6.流结束:读文件可以通过EOFException异常来判断读取文件结束。
序列化概括
1.当父类实现了Serializable接口,则所有的子类都可以序列化;子类实现了Serializable接口父类没有实现,则父类中的属性不能被序列化,会有数据丢失
2.如果实现了Serializable接口,类中包含引用类型的属性,则该属性必须可序列化,否则报错。可以通过Externalizable接口进行自定义的序列化
3.反序列化时如果serialVersionUID修改的化,则反序列化失败
4.在Java环境下使用序列化机制VM支持的都是很好的,但是在多语言环境下可以使用别的序列化机制,例如xml、json等
对象克隆
在java面向对象的编程当中,要复制引用类型的对象,就必须克隆这些对象。通过调用对所有引用类型和对象都是可用的clone方法,来实现克隆。如果是值类型的实例,那么“=”赋值运算符就可以将源对象的状态逐字节地复制到目标对象中。
Java中有两种不同的克隆方法:浅克隆shallowClone和深克隆deepclone。浅克隆不支持引用类型成员变量的复制,仅仅只是克隆的地址;深克隆支持引用类型成员变量的复制。
浅克隆
浅克隆只会克隆引用类型属性的地址,并不是完整克隆引用类型属性。将会出现源对象和克隆对象的该 属性指向同一个对象属性。在浅克隆种当对象被复制时他本身和其中包含的值类型的成员属性,而引用 类型的成员对象并没有复制。
深克隆
在深克隆种无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象。这里的区别于浅克隆,对于原型对象的所有引用类型的属性对象也复制一份给克隆对象,不是地址复制。