Premise: look at the recent CopyOnWriteArrayList source code, found inside the array array is modified transient keyword, surprised, because CopyOnWriteArrayList can be serialized, saved its internal elements will be serialized, so led to transient thinking: "Transient key variable is modified can be serialized"
Transient Keywords
1.transient first impression keyword: the modified variables which can not be serialized (verification examples below)
Entity
public class TestStream implements Serializable {
private String id;
private transient String name;
private transient volatile Object[] array;
private transient Integer age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object[] getArray() {
return array;
}
public void setArray(Object[] array) {
this.array = array;
}
@Override
public String toString() {
return "TestStream{" +
"id='" + id + '\'' +
"age='" + age + '\'' +
", name='" + name + '\'' +
", array=" + Arrays.toString(array) +
'}';
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
复制代码
TestClass
@Test
public void testSeri() throws Exception {
//测试 序列化
TestStream testStream = new TestStream();
testStream.setId("123");
testStream.setName("QBH");
testStream.setArray(new Object[]{1,2,3});
testStream.setAge(18);
System.out.println(testStream);
//将对象读到流里面
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(testStream);
//将对象从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
TestStream object1 = (TestStream)oi.readObject();
System.out.println(object1);
}
复制代码
Result
其中age name array都是被transient修饰的变量,并没有被序列化
TestStream{id='007'age='18', name='juejin', array=[1, 2, 3]}
TestStream{id='007'age='null', name='null', array=null}
复制代码
writeObject和readOject
wirteObject method
When an object "rewrite" this method, the time sequence of calls this method (using reflection to check whether this method be overridden). Know when the method is called, that you can know its use: the custom serialization step
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{}
复制代码
When an object "rewrite" this method, deserialization when calls this method (using reflection to check whether this method be overridden) purposes: to customize the deserialization step
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException{}
复制代码
example
Entity: Inside rewrite the writeObject and readObject methods (CopyOnwriteArrayList also rewrite, cpoy carried out over some of the properties of a custom sequence | deserialization)
package entity;
import java.io.Serializable;
import java.util.Arrays;
import sun.misc.SharedSecrets;
public class TestStream implements Serializable {
private String id;
private transient String name;
private transient volatile Object[] array;//与CopyOnWriteArrayList的数组一致
private transient Integer age;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object[] getArray() {
return array;
}
public void setArray(Object[] array) {
this.array = array;
}
@Override
public String toString() {
return "TestStream{" +
"id='" + id + '\'' +
"age='" + age + '\'' +
", name='" + name + '\'' +
", array=" + Arrays.toString(array) +
'}';
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException {
s.defaultWriteObject();
Object[] elements = getArray();
// Write out array length
s.writeInt(elements.length);//序列化array的长度
s.writeInt(age);//序列化age属性
// Write out all elements in the proper order.
for (Object element : elements)
s.writeObject(element);
}
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
s.defaultReadObject();
int len = s.readInt();//读取数组的长度
setAge(s.readInt());//读取age的值
SharedSecrets.getJavaOISAccess().checkArray(s, Object[].class, len);
Object[] elements = new Object[len];
// Read in all elements in the proper order.
for (int i = 0; i < len; i++)
elements[i] = s.readObject();
setArray(elements);
}
}
复制代码
TestClass
@Test
public void testSeri() throws Exception {
//测试 序列化
TestStream testStream = new TestStream();
testStream.setId("123");
testStream.setName("QBH");
testStream.setArray(new Object[]{1,2,3});
testStream.setAge(18);
System.out.println(testStream);
//将对象读到流里面
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(testStream);
//将对象从流里读出来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
TestStream object1 = (TestStream)oi.readObject();
System.out.println(object1);
}
复制代码
Result
name 和 array 都被反序列化了
TestStream{id='007'age='18', name='juejin', array=[1, 2, 3]}
TestStream{id='007'age='18', name='null', array=[1, 2, 3]}
复制代码
to sum up
So the transient property is not modified can not be serialized. But the property order to write and read correspondence, serialization error occurs otherwise
Think
Why CopyOnWriteArrayList were transient modification of the array, but also to override it writeObject and readObject be serialized? ?
: CopyOnWriteArrayList because the array is a "prime group", the capacity of the array is generally not equal to the actual number of elements, so avoid inconsistency issue in the number of array elements deserialization time (from a written test that is simple version List be), the overwriting step sequence.
此篇文章涉及序列化的知识很浅,只介绍了如何进行定制序列化,如果想要了解序列化的更深的知识,可debug源码进行跟踪