Java 序列化详解及简单实现实例

网友投稿 233 2023-06-05


Java 序列化详解及简单实现实例

一、序列化

序列化定义:序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

目的:

以某种存储形式使自定义对象持久化

将对象从一个地方传递到另一个地方

二、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.谨慎地设计实现SeriHUovztalizable接口

实现发布了就是一种承诺

如果一个类是为继承设计的,在‘允许子类实现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 " + HUovztend);

}

}

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;

}

}

五、序列化算法

将对象实例相关的类元数据输出。

递归地输出类的超类描述直到不再有超类。

类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值。

从上至下递归输出实例的数据

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:java 完全二叉树的构建与四种遍历方法示例
下一篇:SSM框架+Plupload实现分块上传大文件示例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~