Are Transient keyword modified variables can be serialized

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源码进行跟踪

Guess you like

Origin juejin.im/post/5d60b95e6fb9a06ae57cfa75
Recommended