首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

您所不知道的Java序列化

2012-12-18 
你所不知道的Java序列化我们都知道,Java序列化可以让我们记录下运行时的对象状态(对象实例域的值),也就是

你所不知道的Java序列化

我们都知道,Java序列化可以让我们记录下运行时的对象状态(对象实例域的值),也就是我们经常说的对象持久化 。这个过程其实是非常复杂的,这里我们就好好理解一下Java的对象序列化。

?

1、首先我们要搞清楚,Java对象序列化是将 对象的实例域数据( 包括private私有域) 进行持久化存储。而并非是将整个对象所属的类信息进行存储。 其实了解JVM的话,我们就能明白这一点了。实际上堆中所存储的对象包含了实例域数据值以及指向类信息的地址,而对象所属的类信息却存放在方法区中。当我们要对持久层数据反序列化成对象的时候,也就只需要将实例域数据值存放在新创建的对象中即可。

?

2、我们都知道凡要序列化的类都必须实现Serializable接口。 但是不是所有类都可以序列化呢?当然不是这样,想想看序列化可以让我们轻而易举的接触到对象的私有数据域,这是多么危险的漏洞呀!总结一下,JDK中有四种类型的类对象是绝对不能序列化的 。

???? (1) 太依赖于底层实现的类(too closely tied to native code)。比如java.util.zip.Deflater。?

???? (2) 对象的状态依赖于虚拟机内部和不停变化的运行时环境。比如java.lang.Thread, java.io.InputStream
???? (3) 涉及到潜在的安全性问题。比如:java.lang.SecurityManager, java.security.MessageDigest
???? (4) 全是静态域的类,没有对象实例数据。要知道静态域本身也是存储在方法区中的。

?

3、自定义的类只要实现了Serializable接口,是不是都可以序列化呢? 当然也不是这样,看看下面的例子:

//自定义的一个可序列化的ZipFile,当然这个类不能继承JDK中的ZipFile,否则序列化将不可能完成。class SerializableZipFile implements Serializable{public ZipFile zf;//包含一个ZipFile对象SerializableZipFile(String filename) throws IOException{zf=new ZipFile(filename);}//对ZipFile中的文件名进行序列化,因为它是String类型的private void writeObject(ObjectOutputStream out)throws IOException{out.writeObject(zf.getName());}//对应的,反序列化过程中JVM也会检查类似的一个私有方法。private void readObject(ObjectInputStream in)throws IOException,ClassNotFoundException{String filename=(String)in.readObject();zf=new ZipFile(filename);}}//测试public static void main(String[] args) throws IOException, ClassNotFoundException{//序列化 File file=new File("E:/aaa.txt");ObjectOutputStream oout=new ObjectOutputStream(new FileOutputStream(file));oout.writeObject(new SerializableZipFile("e:/aaa.zip"));oout.close();System.out.println("序列化成功");//反序列化ObjectInputStream oin=new ObjectInputStream(new FileInputStream(file));Object o=oin.readObject();oin.close();System.out.println("反序列化成功:"+((SerializableZipFile) o).zf.getName());}//序列化成功//反序列化成功:e:\aaa.zip

????? 太棒了,我们构造了一个可序列化的ZipFile类。这真是一件伟大的事情。

热点排行