ArrayList源码分析——如何实现Serializable
来源:互联网 发布:日本三菱材料数据造假 编辑:程序博客网 时间:2024/06/04 18:51
出处:http://java-road-126-com.iteye.com/blog/1463313
首先,序列化的实现方式:实现Serializable;如果提供了writeObject方法,就会在序列化的时候执行这个方法。看看ArrayList有是如何实现这个方法的。从如下源码中,很容易看到的一点是循环时i<size而不是i<elementData.length,看出端倪了吧,原来,序列化时,我们完全没有必要序列化elementData的所有值。
- private void writeObject(java.io.ObjectOutputStream s)
- throws java.io.IOException{
- // Write out element count, and any hidden stuff
- int expectedModCount = modCount;
- s.defaultWriteObject();
- // Write out array length
- s.writeInt(elementData.length);
- // Write out all elements in the proper order.
- for (int i=0; i<size; i++)
- s.writeObject(elementData[i]);
- if (modCount != expectedModCount) {
- throw new ConcurrentModificationException();
- }
- }
看这段源码又引出另外一个问题既然该方法是private的,那到底序列化的时候会不会派上用场呢?解决疑问的最好方式是实践,debug。如下是测试源码:
- List<String> a = new ArrayList<String>();
- a.add("hello");
- a.add("world");
- try {
- ByteArrayOutputStream st = new ByteArrayOutputStream();
- ObjectOutputStream out = new ObjectOutputStream(st);
- out.writeObject(a);
- byte[] alBytes = st.toByteArray();
- ArrayList<String> all = null;
- try {
- all = (ArrayList<String>) new ObjectInputStream(
- new ByteArrayInputStream(alBytes)).readObject();
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- for(String s : all) {
- System.out.println(s);
- }
- } catch(IOException e) {
- }
接下来,我们再看看ObjectOutputStream的writeObject又做了哪些事情。它会根据传进来的ArrayList对象得到Class,然后再包装成ObjectStreamClass,在writeSerialData方法里,会调用ObjectStreamClass的invokeWriteObject方法,最重要的代码如下:
- writeObjectMethod.invoke(obj, new Object[]{ out });
实例变量writeObjectMethod的赋值方式如下:
- writeObjectMethod = getPrivateMethod(cl, "writeObject",
- new Class[] { ObjectOutputStream.class },
- Void.TYPE);
- private static Method getPrivateMethod(Class cl, String name,
- Class[] argTypes,
- Class returnType)
- {
- try {
- Method meth = cl.getDeclaredMethod(name, argTypes);
- //*****通过反射访问对象的private方法
- meth.setAccessible(true);
- int mods = meth.getModifiers();
- return ((meth.getReturnType() == returnType) &&
- ((mods & Modifier.STATIC) == 0) &&
- ((mods & Modifier.PRIVATE) != 0)) ? meth : null;
- } catch (NoSuchMethodException ex) {
- return null;
- }
- }
到此为止,我们已经很清楚的掌握ArrayList的序列化过程。再看看HashMap等其他容器类,序列化的实现都如出一辙。
反序列化的过程是调用readObject方法,有了writeObject介绍,这个方法就不用介绍了吧,你懂的!
- private void readObject(java.io.ObjectInputStream s)
- throws java.io.IOException, ClassNotFoundException {
- // Read in size, and any hidden stuff
- s.defaultReadObject();
- // Read in array length and allocate array
- int arrayLength = s.readInt();
- Object[] a = elementData = new Object[arrayLength];
- // Read in all elements in the proper order.
- for (int i=0; i<size; i++)
- a[i] = s.readObject();
- }
0 0
- ArrayList源码分析——如何实现Serializable
- 源码分析—ArrayList
- ArrayList——ArrayList.add()源码分析
- Java集合ArrayList实现原理——源码分析
- Java基础——ArrayList源码分析
- JDK——ArrayList源码分析
- java集合框架之ArrayList源码分析——如何扩展容量
- Serializable源码分析笔记
- 集合之ArrayList实现源码分析
- java核心之集合框架——ArrayList源码分析
- java容器类源码分析——ArrayList
- java集合框架03——ArrayList和源码分析
- java集合框架03——ArrayList和源码分析
- Java 集合框架源码分析(一)——ArrayList
- Java 集合框架源码分析(一)——ArrayList
- Java-Collection源码分析(四)——ArrayList
- java集合框架02——ArrayList和源码分析
- [转载]java集合框架——ArrayList和源码分析
- test2
- SSL 弱 密码套件 注册表 配置
- 使用webview时代码不执行的问题
- git安装配置
- HashTable的使用,扑克牌发牌游戏
- ArrayList源码分析——如何实现Serializable
- sqlite大量数据插入优化总结
- MySQL备份恢复之XtraBackup
- DLL的概念、dll导出类(转贴)
- POJ 3074 Sudoku 解题报告(Dancing Link)
- 自定义spring容器
- 移植libgsm_1.0.13
- 强大的ruby,居然给我报死锁
- ClassNotFoundException NoClassDefFoundError 区别