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

ArrayList源码分析——怎么实现Serializable

2012-09-09 
ArrayList源码分析——如何实现Serializable???? 首先,序列化的实现方式:实现Serializable;如果提供了writeO

ArrayList源码分析——如何实现Serializable

???? 首先,序列化的实现方式:实现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 stuffint 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 stuffs.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();    }

热点排行