当你创建对象,只要你需要他会一直存在,直到JVM关闭后,对象不复存在。尽管这么做是有意思的,但是存在一些特殊情况.如何能保证JVM关闭后,对象一直存在呢?
序列化机制,可以通过将信息写入文件或者数据库来达到相同的目的. JAVA 序列化屏蔽了所有的细节,将会使用非常方便、简单。
Java序列化是将那些实现了Serialiable接口的对象转换成一个字节序列,并能够在以后的通过字节序列返回原始对象.而且可以通过网络进行。这意味着序列化可以弥补系统之间的差异,我可以在Linux环境中创建对象通过Socket 传输异构的平台Windows恢复它.
序列化是非常有趣的,可以利用它实现轻量级的持久化."持久化"意味着一个对象的生命周期并不取决于JVM正在执行,可以将对象写入磁盘。然后在需要的时候重新恢复它.
序列化加入到语言之中主要特性:
- Java的远程方法调用(Remote Method Invocation),(EJB 的核心啊,当然还包括了SessionBean EntryBean MessageDriverBean 远程接口,本地接口等等.. 哥们现在一直在使用中EJB,当然工作中需要的。据哥们自己理解Spring/Hibernation框架的灵感来自于EJB.也许EJB 太重量级了才会有今天的下场,不够我要强调的是EJB的分布式能力Spring还是差一些) 保证使用存货于其他机器上的对象好像在本地JVM中一样.
- 向远程对象发送消息,通过对象序列化来传输消息(WebService\MQ消息中间件现在使用最多的异构平台数据互换通信...)
上面废话了这么多(会写程序只是一方面,会给别人讲解到才是真正的理解到了)。那我们如何实现一个序列化呢?
- 实现java.io.Serialiable接口(声明式接口,不需要实现任何方法),Java中许多类库都已经实现了序列化--基本数据类型的封装器,集合。。。。。。
- 因为对象序列化是基于字节的所以无可厚非(InputStream OutputStream)跑不了, 我们看下API结构,java Io 实现了很多类,总结起来:基于介质(磁盘、内存、网络)或者基于传输方式的(字节、字符、Java NewIO 是基于数据块(就是一个大数组)的所以要比IO快很多)来提供了一堆适配器 Buffered/Data/Object.....DataInputStream/DataOutputStream这个好像很像:提供了很多的方法总结起来java的基础数据类型读写方法都存在.呀好兴奋。但是在在仔细看,都是基础数据类型,我们项目中有一个POJO对象实现了序列化,POJO中存在100多个成员变量,难道要写100.WriteXXX.而写读的时候还要写ReadXXX,这还是次要的顺序怎么办?想到就头大了。不过幸亏有ObjectInputStream/ObjectOutputStream.
- java序列化非常聪明,它保存了对象的全景图,能够追踪到对象中的引用,对象引用的引用,引用中的引用。。。。。。O(∩_∩)O哈哈哈~
实战序列化
public class Data implements java.io.Serializable {
private int n;
public Data(int n) {
this.n = n;
}
public String toString() {
return Integer.toString(n);
}
}
<pre class="java" name="code">import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Arrays;
import java.util.Random;
public class DataPersistent implements java.io.Serializable {
private Random random = new Random(10);
private Data[] data = { new Data(random.nextInt(10)), new Data(random.nextInt(10)), new Data(random.nextInt(10)) };
private char c;
private int index;
public DataPersistent(char c, int index) {
this.c = c;
this.index = index;
}
public String toString() {
return c + Integer.toString(index) + Arrays.toString(data);
}
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
DataPersistent obj = new DataPersistent('a', 1);
ObjectOutputStream output = new ObjectOutputStream(new FileOutputStream(new File("")));
output.writeObject(obj);
output.close();
ObjectInputStream input = new ObjectInputStream(new FileInputStream(new File("")));
DataPersistent obj2 = (DataPersistent) input.readObject();
input.close();
}
}
</pre>而已通过添加System.out去打印一些东西.可以将存储介质修改为ByteArrayOutputStream.就可以实现深层Clone了.1. 修改以上代码添加构造函数中输出一些信息,新增一个默认的构造函数,试一下从字节中恢复对象有没有调用构造器呢 ?注意啦,当一个implements java.io.Serializable序列化对象还原中,没有调用任何构造器,人只是默认的构造器.整个对象都是从InputStream恢复过来的.那从字节码中恢复对象,有哪些工作要做呢?加入我们讲一个对象序列化持久化文件,把这个文件扔给你或者通过网络传输到其他的机器上,那就能还原了? readObject 对象为什么要抛出ClassNotFoundException可以自己做一个实验,实现会告诉你一切的.Class对象依赖于*.class,由ClassLoader(委托加载机制)加载字节码,解析验证后生成Class对象,所以一定要保证CLASSPATH中有XXX.class文件.</p><p></p><pre>