该文章会的简要目录如下:
- Serialization的概述
- 用‘transient’进行性能优化
- 关键点总结
Serializtion的概述
Serializtion是将一个完整的JAVA对象写入输出流的过程,这个流可以是文件,字节数组或者TCP/IP相关的Socket流。
Deserializtion就是反序列化,也就是说将一个完整的JAVA对象从输入流里读取出来。
JAVA类必须如果实现 java.io.Serializable或 java.io.Externalizable 接口,也可以继承实现了这些接口的超类。那么此JAVA对象就被序列化或者反序列化了。
所以的基本数据类型和一些JAVA API类都是进行了序列化的,你不必要进行额外的序列化。
如果你使用Externalizable可以定制你的序列化方式。这篇文章主要关注的是Serializtion接口
Serializable接口是一个标志位接口,他没有任何的接口方法。像EJB,RMI,ATG这些主流的JAVA技术都是基于序列化进行对象传输的,这些技术本身都暗中的将你的对象进行了序列化的操作。。
下面两个方法可以使对象写入流或者从流中读取对象。
ObjectInputStream.readObject(); // to read object
ObjectInputStream.writeObject(Object obj); // to write object
序列化机制
当你用序列化从网络中读或者写一个对象到文件中去的时候,这个完整对象意味着对象本身以及他的初始化变量,还有超类的变量。Transient的排除在外。你可以看一下下面这幅图来加深理解。
在这个类关系视图下,当我将CorporateEmployee对象写入到文件中去的时候,会先初始化Address, 再初始化SecondAddress,然后调用Employee,最后再调用到CorporateEmployee本身。这样一个完整的对象就被加载完毕。通过这种加载方式,你会发现,他会将写入所有的东西直到类关系走完。
用‘transient’进行性能优化
如果变量用transient进行修饰的话,此变量就会被输入流或者输出量直接忽略,这样的一个好处就是我们可以通过使用trsnsient来避免一些不必要的数据写入流里。
下面是一段测试代码:
public class SerializationTest { static long start, end; OutputStream out = null; InputStream in = null; OutputStream outBuffer = null; InputStream inBuffer = null; ObjectOutputStream objectOut = null; ObjectInputStream objectIn = null; public Person getObject() { Person p = new Person("SID", "austin"); Vector v = new Vector(); for (int i = 0; i < 7000; i++) { v.addElement("StringObject" + i); } p.setData(v); return p; } public static void main(String[] args) { SerializationTest st = new SerializationTest(); start = System.currentTimeMillis(); st.writeObject(); st.readObject(); end = System.currentTimeMillis(); System.out.println("Time taken for writing and reading :" + (end - start) + "milli seconds"); } public void readObject() { try { in = new FileInputStream("c:/temp/test.txt"); inBuffer = new BufferedInputStream(in); objectIn = new ObjectInputStream(inBuffer); objectIn.readObject(); } catch (Exception e) { e.printStackTrace(); } finally { if (objectIn != null) try { objectIn.close(); } catch (IOException e) { e.printStackTrace(); } } } public void writeObject() { try { out = new FileOutputStream("c:/temp/test.txt"); outBuffer = new BufferedOutputStream(out); objectOut = new ObjectOutputStream(outBuffer); objectOut.writeObject(getObject()); } catch (Exception e) { e.printStackTrace(); } finally { if (objectOut != null) try { objectOut.close(); } catch (IOException e) { e.printStackTrace(); } } } }
public class Person implements Serializable { private String name; private Vector data; private String address; public Person(String name, String address) { this.name = name; this.address = address; } public String getAddress() { return address; } public Vector getData() { return data; } public String getName() { return name; } public void setData(Vector data) { this.data = data; } }
执行这段代码,会得到以下结论:
Time taken for writing and reading :96milli seconds
如果此时将“private Vector data”改为“ private transient Vector data;”再执行这段代码,你会发现:
Time taken for writing and reading : 31milli seconds
关键点总结
1.使用transient关键字将不需要进行序列化的数据忽略。
2.当你在使用RMI,EJB,ATG等技术时,请使用JAVA Serialiable内建的序列来传输对象,同时配合transient关键字进行变量过滤。
我也添加你了亲爱的。常来常往
I’m not sure exactly why but this website is loading very slow for me. Is anyone else having this problem or is it a issue on my end? I’ll check back later and see if the problem still exists.