在Itr.hasNext()方法中: public boolean hasNext() { return cursor != size(); }
調用了AbstractList的size()方法,比較當前光標位置是否越界。
在Itr.next()方法中,Itr也調用了定義在AbstractList中的get(int)方法,返回當前光標處的元素: public Object next() { try { Object next = get(cursor); checkForComodification(); lastRet = cursor++; return next; } catch(IndexOutOfBoundsException e) { checkForComodification(); throw new NoSUChElementException(); } }
注重,在next()方法中調用了checkForComodification()方法,進行對修改的同步檢查: final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
private static final long serialVersionUID = 8683452581122892189L;
private transient Object elementData[];
private int size;
可以看出serialVersionUID和size都將自動序列化到介質中,但elementData數組對象卻定義為transient了。也就是說ArrayList中的所有這些元素都不會自動系列化到介質中。為什么要這樣實現?因為elementData數組中存儲的“元素”其實僅是對這些元素的一個引用,并不是真正的對象,序列化一個對象的引用是毫無意義的,因為序列化是為了反序列化,當你反序列化時,這些對象的引用已經不可能指向原來的對象了。所以在這兒需要手工的對ArrayList的元素進行序列化操作。這就是writeObject()的作用。 private synchronized void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ // Write out element count, and any hidden stuff s.defaultWriteObject(); // Write out array length s.writeInt(elementData.length); // Write out all elements in the proper order. for (int i=0; i s.writeObject(elementData[i]); }
這樣元素數組elementData中的所以元素對象就可以正確地序列化到存儲介質了。 對應的readObject()也按照writeObject()方法的順序從輸入流中讀?。?br /> private synchronized 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(); elementData = new Object[arrayLength]; // Read in all elements in the proper order. for (int i=0; i elementData[i] = s.readObject(); }