前提: CopyOnWriteArrayListとをシリアル化することができるので、驚いて、配列arrayは、transientキーワードを変更された中に発見、最近CopyOnWriteArrayListとソースコードを見ては、その内部の要素が過渡につながった、シリアライズされます保存しました思考:「一時キー変数が変更されてはシリアライズすることができます」
過渡キーワード
1.transient最初のインプレッションキーワード:シリアル化することができない修飾変数(以下検証例)
エンティティ
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);
}
复制代码
結果
其中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方法
オブジェクトは(このメソッドをオーバーライドするかどうかを確認するためにリフレクションを使用して)このメソッド呼び出しの時系列この方法を「書き換え」場合。メソッドが呼び出されたときに、その使用を知ることができることを、知っている:カスタムのシリアル化のステップを
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{}
复制代码
デシリアライゼーションステップをカスタマイズする:コールこのメソッド(このメソッドをオーバーライドするかどうかを確認するためにリフレクションを使用して)目的の場合、オブジェクトは、デシリアライズし、この方法を「書き換え」場合
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException{}
复制代码
例
エンティティ:内部では、writeObjectメソッドとreadObjectメソッドを書き換える(CopyOnWriteArrayListともcpoyは、カスタムシーケンスのプロパティの一部にわたって実施、書き換え|直列化復元)
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);
}
复制代码
結果
name 和 array 都被反序列化了
TestStream{id='007'age='18', name='juejin', array=[1, 2, 3]}
TestStream{id='007'age='18', name='null', array=[1, 2, 3]}
复制代码
概要
シリアライズすることはできませんので、過渡特性は変更されません。しかし、対応を読み書きするプロパティのためには、シリアル化のエラーが発生しそう
考えます
なぜCopyOnWriteArrayListとは、アレイの過渡変更があったが、また、writeObjectメソッドとreadObjectをシリアル化することをオーバーライドしますか??
:アレイは「プライム基」であるためCopyOnWriteArrayListとは、アレイの容量は、一般に、要素の実際の数と等しくないので、単純なバージョンリストで記述された試験からの配列要素逆シリアル化時間の数(に矛盾の問題を回避します、)上書きステップシーケンスです。
此篇文章涉及序列化的知识很浅,只介绍了如何进行定制序列化,如果想要了解序列化的更深的知识,可debug源码进行跟踪