ArrayList의 경우 학습 서열화 및 반서열화

13435 단어 입출력 흐름

1. 서열화 및 반서열화:


대상 조작 클래스의 실현을 진행할 때 여러 개의 키워드 Serializable와transient가 관련된다
  • 서열화와 반서열화는 무엇입니까?서열화: 대상을 바이트로 바꾸는 과정을 서열화 과정(로컬 디스크에 저장)이라고 한다. 반서열화: 바이트를 대상으로 바꾸는 과정을 반서열화 과정(로컬 디스크에서 읽는 대상)이라고 한다
  • 서열화 응용 장면: 네트워크 전송과 데이터 저장
  • 서열화의 역할: ① 데이터가 네트워크 전송에서 민감한 데이터를 전송하지 않기 위해서는 서열화가 필요하다. ② 대상이 로컬 디스크에 저장되기 위해서는 서열화가 필요하다
  • 서열화 요점: ① 자바에서 클래스만 자바를 실현했다.io.Serializable 인터페이스에서 클래스를 정렬할 수 있습니다. ② 대상의 정렬화와 반정렬화는 ObjectInputStream과 ObjectOutputStream을 통해 작업해야 합니다. ③ 모든 대상 자체에 유일한 표지가 있습니다: SerialVersion UID (직렬 버전 통일 식별자) - 클래스의 서로 다른 버전 간의 호환성을 나타냅니다.(UID의 기본값은 JAVA 컴파일러에 의존하고 같은 클래스에 대해 컴파일러가 다르면 UID가 다를 수 있음) 그 생성 방식은 두 가지가 있다. 1.기본 생성 2.클래스 이름, 인터페이스 이름, 구성원 방법, 속성 등에 따라 64비트의 해시 필드를 자동으로 생성합니다.명시적 정의 UID 역할: a. 서로 다른 버전의 UID b. 클래스 실례를 서열화하고 한 필드를 변경하거나 한 필드를 추가하며 UID를 설정하지 않습니다. 그 어떠한 변경도 클래스 실례를 반서열화하지 못하고 이상을 던질 수 없습니다.UID를 추가하면 이전 인스턴스가 역정렬되고 새로 추가되거나 변경된 필드가 초기 값으로 설정되며 null ④ transient 키워드로 수식된 속성은 서열화 및 역정렬화에 참여하지 않습니다.변수 앞에 이 키워드를 추가합니다. 서열화 과정에서 이 변수는 쓰지 않습니다. 반서열화 과정에서 (읽을 때) 이 변수는 초기 값 (eg: int 형식의 초기 값 0, 대상 형식의 초기 값 null) ⑤ 클래스가 서열화되려면 Serializable 인터페이스를 실현해야 합니다.그렇지 않으면 NotSerializable Exception 이상이 발생합니다. 서열화 작업 과정에서 유형을 검사합니다. 서열화된 클래스는 Enum, Array, Serializable 유형 중 어느 종류에 속해야 하기 때문입니다.
  • 2. ArrayList의 예를 들어 학습 서열화와 반서열화

  • 판독 원본:
  • // ArrayList java.io.Serializable , ArrayList 
    public class ArrayList<E> extends AbstractList<E>
            implements List<E>, RandomAccess, Cloneable, java.io.Serializable
    

    하지만 자바를 눌러주세요.io.Serializable 인터페이스에서 볼 수 있듯이 이것은 빈 인터페이스이다. 이 인터페이스를 어떻게 실현해야만 서열화와 반서열화를 진행할 수 있습니까?이 때 Object OutputStream의 writeObject 방법부터 원인을 찾아야 합니다.
    //ObjectOutputStream writeObject 
     public final void writeObject(Object obj) throws IOException {
            if (enableOverride) {
                writeObjectOverride(obj);
                return;
            }
            try {
                writeObject0(obj, false);   //!!!!!
            } catch (IOException ex) {
                if (depth == 0) {
                    writeFatalException(ex);
                }
                throw ex;
            }
        }
    

    원본 코드에서 볼 수 있듯이 Object OutputStream의 writeObject 방법에서 writeObject0 () 방법을 호출했습니다
     private void writeObject0(Object obj, boolean unshared)
            throws IOException
        {
          // remaining cases
                if (obj instanceof String) {
                    writeString((String) obj, unshared);
                } else if (cl.isArray()) {
                    writeArray(obj, desc, unshared);
                } else if (obj instanceof Enum) {
                    writeEnum((Enum) obj, desc, unshared);
                } else if (obj instanceof Serializable) {
                    writeOrdinaryObject(obj, desc, unshared);
                } else {
                    if (extendedDebugInfo) {
                        throw new NotSerializableException(
                            cl.getName() + "
    "
    + debugInfoStack.toString()); } else { throw new NotSerializableException(cl.getName()); } }

    writeObject0 방법에서 서열화 작업을 할 때 서열화될 클래스가 String, Enum, Array, Serializable 형식인지 판단하고, 그렇지 않으면 NotSerializable Exception(서열화 이상 없음)을 직접 던집니다. 대상이 Serializable 형식이라면 writeOrdinary Object 방법으로 조정하여 이 방법에서 서열화 데이터를 쓰는 방법인 writeSerialization(obj, desc)이 있습니다.이 방법 중에는 invokeWrite Object(obj,this) 방법이 있는데 대상의 출력을 통해 대상에 흐르는 것을 쓸 수 있다. 그러면 Serializable와 서열화와 반서열화를 연결할 수 있다.
     void invokeWriteObject(Object obj, ObjectOutputStream out)
            throws IOException, UnsupportedOperationException
    
      private static final long serialVersionUID = 8683452581122892189L;  // 
    

    Array List는 실제적으로 동적 수조로 매번 가득 채운 후에 자동으로 증가하는 길이를 설정합니다. 만약에 수조가 자동으로 증가하는 길이를 100으로 설정하고 실제적으로 원소 하나만 놓으면 99개의null 원소를 서열화합니다. 그러면 대량의 빈 대상을 포함하는 수조가 서열화되는 것을 방지하기 위해 저장을 최적화하기 위해 Array List는transient를 사용하여 저장 대상을 설명하는 수조element Data[]를 사용합니다.
      private transient Object[] elementData;
    

    그러나 하나의 집합으로서 서열화 과정에서 그 중의 원소가 오래 지속될 수 있도록 해야 하기 때문에 write Object와readObject 방법을 다시 쓰는 방식으로 그 중의 원소를 보존한다.writeObject 방법은 요소 데이터 그룹의 요소를 출력 흐름 (Object OutputStream) 에 두루 저장합니다.readObject 방법은 입력 흐름 (ObjectInputStream) 에서 대상을 읽고 값을 요소 데이터 그룹에 저장합니다.
    //ArrayList writeObject readObject 
     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를 추가하는 방법???그러면 또 하나의 문제가 있습니다. Array List에 write Object와read Object 방법이 쓰여 있지만 이 두 가지 방법은 호출되지 않았습니다.만약 하나의 클래스에 write Object와readObject 방법이 포함된다면 이 두 가지 방법은 어떻게 호출됩니까?답: Object OutputStream의 write Object 방법과 Object InputStream의readObject 방법을 사용할 때 반사reflect로 호출됩니다.

    좋은 웹페이지 즐겨찾기