과도 키워드 수정 변수는 직렬화 할 수 있습니까

전제가 : 으로 CopyOnWriteArrayList 직렬화 할 수 있기 때문에 배열 배열 안에서 발견 최근으로 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 방법

때 객체 "재 작성"이 방법을 호출 (이 방법은 오버라이드 (override) 할 수 있는지 여부를 확인하는 반사를 사용하여)이 메소드의 시간 순서. 메소드가 호출 될 때 당신이 사용을 알 수 있다는 것을 알고 : 사용자 정의 직렬화 단계를

private void writeObject(java.io.ObjectOutputStream s)
      throws java.io.IOException{}
复制代码

객체 "재 작성"이 방법 직렬화는이 메소드를 호출 (이 방법은 오버라이드 (override) 할 수 있는지 여부를 확인하는 반사를 사용하여) 목적이 경우 경우 : 직렬화 단계를 사용자 정의 할 수

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

추천

출처juejin.im/post/5d60b95e6fb9a06ae57cfa75