首先,序列化的实现方式:实现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();
}
分享到:
相关推荐
根据arraylist源码分析,自己编写了一个类似于arraylist集合的代码
ArrayList的源码,写了一些自己的分析,包括jdk1.8的新特性
ArrayList源码分析_016.pdf
ArrayList源码解析(数据结构及底层实现)(csdn)————程序
ArrayList 源码深度解析 一、重新认识ArrayList 什么是ArrayList? ArrayList是基于数组实现的List类,封装了一个动态再分配的Object数组,以达到可以动态增长和缩减的索引序列。 长啥样? 如图,是一个长度为6,...
来自视频课笔记 面试肯定没问题 包含线程安全的list和不安全的list
ArrayList源码.zip
基于jdk1.8 的ArrayList的源码分析 前言:一说到ArrayList的大家可能立马想到的就是:有序、可重复、查找快但是增删慢、线程不安全。但是具体的原因都不是很清楚,本文就会根据这些问题和大家一起去学习。主要会从...
反编译系统的,只是做个例子。 为了凑够20个字,我多打几个字……
浅析ArrayList内部实现 资源源于不但搜索,自由源于不但努力
JDK8的ArrayList源码文件
ArrayList最新源码,基于Jdk1.8
主要为大家详细介绍了Java集合框架ArrayList源码分析,感兴趣的小伙伴们可以参考一下
主要介绍了Java编程中ArrayList源码分析,具有一定借鉴价值,需要的朋友可以参考下。
一 前言 知识追寻者目前的系列都是基于jdk1.8进行学习分析;...二 ArrayList源码分析 2.2 空参构造方法源码分析 调试代码 public static void main(String[] args) { // 初始化长度为0 ArrayList list =
ArrayList源码阅读笔记 -- 介绍了ArrayList 普通增删改查的过程,从构造空参构造方法,然后添加元素,修改元素,删除元素,获取元素.
第二章 ArrayList源码解析一、对于ArrayList需要掌握的七点内容ArrayList的创建:即构造器获取ArrayList中的单个对象:即get(i
源码分析见我博文:http://blog.csdn.net/wabiaozia/article/details/50684556