用transient修飾的成員變數不能序列化,為什麼ArrayList集合可以實現序列化
阿新 • • 發佈:2019-01-09
序列化有2種方式:
A、只是實現了Serializable介面。
序列化時,呼叫java.io.ObjectOutputStream的defaultWriteObject方法,將物件序列化。
注意:此時transient修飾的欄位,不會被序列化。
B、實現了Serializable介面,同時提供了writeObject方法。
序列化時,會呼叫該類的writeObject方法。而不是java.io.ObjectOutputStream的defaultWriteObject方法。
Java程式碼
ArrayList實現了java.io.Serializable,複寫了以下2個方法:
private void writeObject(java.io.ObjectOutputStream s)
private void readObject(java.io.ObjectInputStream s)
從原始碼中可以看出,先呼叫java.io.ObjectOutputStream的defaultWriteObject方法,進行預設的序列化操作,此時transient修飾的欄位,沒有被序列化。
接著:for迴圈,將陣列中的元素寫出,序列化。而陣列中的元素正是transient。
PS:反序列化,也是這樣。
A、只是實現了Serializable介面。
序列化時,呼叫java.io.ObjectOutputStream的defaultWriteObject方法,將物件序列化。
注意:此時transient修飾的欄位,不會被序列化。
B、實現了Serializable介面,同時提供了writeObject方法。
序列化時,會呼叫該類的writeObject方法。而不是java.io.ObjectOutputStream的defaultWriteObject方法。
注意:此時transient修飾的欄位,是否會被序列化,取決於writeObject。
ArrayList的原始碼:
Java程式碼
- 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();
- }
- }
ArrayList實現了java.io.Serializable,複寫了以下2個方法:
private void writeObject(java.io.ObjectOutputStream s)
private void readObject(java.io.ObjectInputStream s)
從原始碼中可以看出,先呼叫java.io.ObjectOutputStream的defaultWriteObject方法,進行預設的序列化操作,此時transient修飾的欄位,沒有被序列化。
接著:for迴圈,將陣列中的元素寫出,序列化。而陣列中的元素正是transient。
PS:反序列化,也是這樣。