快速做网站,番禺人才招聘网,云南餐饮网站建设,家乡土特产营销策划方案一、基本概念Serializable接口#xff1a;1. 实现了Serializable接口的类#xff0c;可以进行序列化和反序列化#xff1b;没有实现这个接口的类的任何(state)状态/域或者属性值不能被序列化2. All subtypes of a serializable class are themselves serializable. 所有实现…一、基本概念Serializable接口1. 实现了Serializable接口的类可以进行序列化和反序列化没有实现这个接口的类的任何(state)状态/域或者属性值不能被序列化2. All subtypes of a serializable class are themselves serializable. 所有实现了序列话接口的类的子类是可以被序列化的3. 为了让不能序列化的类的子类能够被序列化子类要能够保存和恢复(restore)父类的public/protected和package fields只有在父类具有无参构造函数去初始化其域的情况下子类才能保存和恢复父类的public/protectes和package fields如果不是这种情况声明一个可序列化的类是有问题的并且在运行期即可以检测到这个错误4.在反序列化的过程中不能序列化的类对应的域将会用这个类的public或者protected修饰的无参构造方法进行初始化无参的构造方法必须是可序列化的子类有访问权限的可序列化子类的域将从流中恢复回来。5.在序列化和反序列化的过程中这些类都需要经过特殊的处理也就是需要去实现特殊的方法* private void writeObject(java.io.ObjectOutputStream out)* throws IOException* private void readObject(java.io.ObjectInputStream in)* throws IOException, ClassNotFoundException;* private void readObjectNoData()* throws ObjectStreamException;* 5.1 WriteObject方法1) WriteObject方法用来将特定类的对象的域写入这样对应的可读对象可以将这些域恢复回来。2)默认的存储对象域的机制可以通过调用方法out.defaultWriteObject()来实现这个方法不需要去将它自己和属于父类或者子类的域相关联起来3)类的状态通过调用writeObject()方法或者用数据输出(DataOutput)所支持的针对原生(primitive)数据类型的方法来将类所拥有的域写入到对象输出流(ObjectOutputStream)中来保存起来5.2 readObject方法1)readObject方法用来读流并将类的域恢复回来。2)readObject方法可以调用in.defaultReadObject方法来执行恢复类的没有static和transient修饰的域的默认机制。这个in.defaultReadObject方法利用流中的信息来用当前对象的对应名字的域来分配存储在流中的对象的域。这解决了类在后期增加新的域的情况。3)类的状态通过调用writeObject()方法或者用数据输出(DataOutput)所支持的针对原生(primitive)数据类型的方法来将类所拥有的域写入到对象输出流(ObjectOutputStream)中来保存起来5.3 readObjectNoData方法1)readObjectNoData方法用来在序列化的流没有列出所给出的类(这个类是被反序列化的对象的一个父类)的情况下去初始化这个类的对象的域。这种情况出现在接受方用了一个和发送方不同版本反序列化实例的类并且这个接收方的版本所继承的类并没有被发送方的版本所继承这种情况也可能出现在序列化的流已经被篡改2)因此在有一个不利的或者不完整的流的情况下readObjectNoData方法对于去合理的初始化反序列化对象是非常有用的6. 在将一个对象写入到流中的时候需要指派一个可替代的对象去使用的可序列化类要去实现下面的方法* ANY-ACCESS-MODIFIER Object writeReplace() throws ObjectStreamException;* 1)如果这个方法存在那么这个方法应该在被序列化的时候调用2)这个方法需要能被在类的作用域下的其他方法访问因此这个方法有public/protected/private访问权限3)子类访问这个方法遵循java的权限访问规则7. 当一个类的实例从流读出的时候这个类需要指派一个可替代的对象应该要去实现下面的方法* ANY-ACCESS-MODIFIER Object readResolve() throws ObjectStreamException;* 机制和writeReplace方法类似8.序列化版本唯一标识-SerialVersionUID1. 定义在序列化运行时期会将每一个可序列化类和一个版本号关联起来这个版本号就叫做SerialVersionUID2. 作用这个序列化唯一标识的作用是为了式一个可序列化的对象发送方和接收方在装载那个对象的类时相对于序列化是匹配的3. 当接受方装载了一个对象的类和对应接收方装载的类有不同的序列化唯一标识的时候就会导致InvalidClassException4. 一个可序列化的类可以显示声明一个SerialVersionUID这个序列化唯一标识需要被static/final/long修饰* ANY-ACCESS-MODIFIER static final long serialVersionUID 42L;* 5. 如果一个可序列化的类不显示声明SerialVersionUID那么将会基于这个类的很多方法计算一个默认的SerialVersionuid值但是强烈建议显示声明为了兼容不不同的编译器也建议SerialVersionUID被private修饰从而不能被继承因为继承了也没有很大意义。6.数组不需要显式声明序列化版本唯一标识对于数组类而言需要接收方和发送方的序列化唯一标识是一致的已经被废弃了的。author unascribed* see java.io.ObjectOutputStream* see java.io.ObjectInputStream* see java.io.ObjectOutput* see java.io.ObjectInput* see java.io.Externalizable* since JDK1.1*/public interface Serializable {}二、序列化和反序列化java对象序列化是将那些实现了Serializable接口的对象转换为一个字节序列并能够在以后将这个字节序列完全恢复为原来的对象(反序列化)1. 为什么需要序列化一般创建的对象在程序关闭(JVM关闭)的时候创建的对象就不会继续存在了如果对象能够在程序不运行的情况下仍能存在并保存信息那将非常有用尽管可以通过保存到数据库或者存在文件来恢复对象但是序列化可以将一个对象声明是“持久性”的并为我们处理掉细节(持久性意味着一个对象的生存周期并不取决于程序是否还在执行它可以生存于程序的调用之间)2. 序列化和反序列化的作用2.1 Java的远程方法调用(RMI)序列化和反序列化使得存活于其他计算机上的对象使用起来就像是存活于本地上一样序列化和反序列化的过程可以通过网络进行这意味着序列化机制能够自动弥补不同操作系统之间的差异在window操作系统上序列化的对象可以linux操作系统上重新准确组装当向远程对象放消息时需要通过序列化来传输参数和返回值2.2 对于java Beans来说对象的序列化也是必须的使用一个bean时一般情况下是在设计阶段对它的状态信息进行配置。这种状态信息必须保存下来并在程序启动时进行后期恢复。这种具体工作就是由对象序列化完成的。3. 序列化和反序列化如何实现3.1 序列化要序列化一个对象首先要创建某些OutputStream对象然后将其封装在一个ObjectOutputStream对象内。这时只需要调用OutputStream对象的writeObject()方法即可将对象序列化并将其发送给OutputStream。3.2 反序列化要讲一个序列还原为一个对象需要将一个InputStream封装在ObjectInputStream内然后调用readObject();[注]和往常一样我们最后获得的是一个引用它指向一个向上转型的Object所以必须向下转型才能直接设置它们(用(ClassNname))