Java 序列化详解及简单实现实例
程序员文章站
2024-03-05 20:20:31
一、序列化
序列化定义:序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。...
一、序列化
序列化定义:序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
目的:
- 以某种存储形式使自定义对象持久化
- 将对象从一个地方传递到另一个地方
二、java序列化
一个对象能够序列化的前提是实现serializable接口。serializable接口没有方法,更像是个标记。有了这个标记的class就能被序列化机制处理。如下:
class mypoint implements serializable{ }
java反序列化不会调用任何构造器
序列化的控制:externalizable。读写都交给你
- 要在方法writeexternal写入序列化的参数
- 要在方法readexternal读取反序列化的值
- 要有默认的构造方法(readexternal执行完成,再执行默认的构造器)
void writeexternal(objectoutput out) throws ioexception; void readexternal(objectinput in) throws ioexception,classnotfoundexception; public class point implements externalizable { private int a; private int b; public point(int a, int b) { this.a = a; this.b = b; } public point() { } public string tostring() { return a + " , " + b; } public void writeexternal(objectoutput out) throws ioexception { out.write(a); out.write(b); } public void readexternal(objectinput in) throws ioexception, classnotfoundexception { a = in.read(); b = in.read(); } public static void main(string[] args) throws ioexception, classnotfoundexception { string file = "d://1.txt"; point p = new point(1, 2); system.out.println(p); fileoutputstream fos = new fileoutputstream(file); objectoutputstream oos = new objectoutputstream(fos); oos.writeobject(p); fileinputstream fis = new fileinputstream(file); objectinputstream ois = new objectinputstream(fis); point pp = (point) ois.readobject(); system.out.println(pp); } }
- transient关键字 关闭序列化自动进行。
- 不管你选择了哪种序列化形式,都要为自己编写的每个可序列化的类声明一个显示的序列版本uid(serial version uid)
三、序列化的问题
在effective java中列举出了java序列化要注意的一些问题:
1.谨慎地设计实现serializable接口
- 实现发布了就是一种承诺
- 如果一个类是为继承设计的,在‘允许子类实现serializable接口'与‘禁止子类实现serializable接口'取一个折中的方案是:提供一个可访问的无参构造器
2.保护性地编写 readobject()方法,因为readobject()是构建实例的入口。
不保护可能出现 构建了不满足要求的 实例
3.考虑自定义的序列化形式
- 逻辑内容 与 物理表示法
- 如果一个对象的 ‘物理表示法'等同于它的‘逻辑内容',可能就适用于使用默认的序列化形式。
- 如果有更好的 ‘物理表示法'在表示‘逻辑内容'则可以自定义序列化形式。
public class stringlist implements serializable { private transient int size = 0; private transient entity head = null; public final void add(string str) { // ... } private static class entity { string data; entity next; entity previous; } private void writeobject(objectoutputstream s) throws ioexception { s.defaultwriteobject(); s.write(size); for (entity e = head; e != null; e = e.next) { s.writeobject(e.data); } } private void readobject(objectinputstream s) throws ioexception, classnotfoundexception { s.defaultreadobject(); int num = s.read(); for (int i = 0; i < num; i++) { this.add((string) s.readobject()); } } }
四、序列化代理模式
序列化机制提供的钩子函数有:
writereplace writeobject readobject readresolve
- writereplace:序列化的时候替换所要序列化的对象。
- writeobject:写入序列化的对象
- readobject:读取序列化的对象
- readresolve:最后返回序列化对象
import java.io.invalidobjectexception; import java.io.objectinputstream; import java.io.serializable; import java.util.date; public final class period implements serializable { private static final long serialversionuid = 100l; private final date start; private final date end; public period(date start, date end) { this.start = new date(start.gettime()); this.end = new date(end.gettime()); if (this.start.compareto(this.end) > 0) { throw new illegalargumentexception(start + " after " + end); } } public date start() { return new date(start.gettime()); } public date end() { return new date(end.gettime()); } public string tostring() { return start + " - " + end; } // 不给 private object writereplace() { return new serializationproxy(this); } private void readobject(objectinputstream stream) throws invalidobjectexception { throw new invalidobjectexception("proxy request"); } private static class serializationproxy implements serializable { private final date start; private final date end; serializationproxy(period p) { this.start = p.start; this.end = p.end; } private object readresolve() { return new period(start, end); } private static final long serialversionuid = 1000l; } }
五、序列化算法
- 将对象实例相关的类元数据输出。
- 递归地输出类的超类描述直到不再有超类。
- 类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值。
- 从上至下递归输出实例的数据
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
下一篇: asp.net(C#) 开源资源大汇总