Java 시리얼화된 요약(최대)

16608 단어

콘셉트


 
  • Serializable 인터페이스를 실현하는데 이것은 단지 표시 인터페이스일 뿐 실현하지 않아도 서열화할 수 있다
  • RMI: 원격 메소드 호출
  • RPC: 원격 프로세스 호출
  • 시리얼화된 ID

                        ,            
    private static final long serialVersionUID = 1L; //           
    private static final long serialVersionUID = -5453781658505116230L; //        

     

    정적 변수 서열화

  • x*- 서열화는 대상이지 클래스가 아니다. 정적 변수는 클래스 단계에 속하기 때문에 서열화는 정적 변수를 저장하지 않는다
  •  

    부모 클래스 서열화 및 Trancient 키워드

  • 하위 클래스가serializable 인터페이스를 실현했습니다. 상위 클래스가serializable 인터페이스를 실현하지 못하면 하위 클래스를 서열화할 때 하위 클래스의 값을 저장하지 않습니다.
  • 부류 보존값이 필요하고 부류도serializable 인터페이스를 실현해야 한다
  • 부모 대상의 변수 값을 취할 때 부모 클래스의 무참구조 함수를 호출한 값입니다. 예를 들어 int형의 기본값은 0이고string형의 기본값은null입니다. 값을 지정하려면 부모 클래스 구조 방법에서 지정해야 합니다
  • Trancient 키워드에 지정된 컨텐트는 저장되지 않습니다(시리얼화되지 않음)
  • 반서열화된 후transient 변수의 값은 초기 값으로 설정됩니다. 예를 들어 int형은 0이고 대상형은nul
  • 상속 관계를 사용해도 마찬가지로 실현할 수 있다. Trancient와 같은 효과, 즉 부류에 대해 Serializable 인터페이스를 실현할 필요가 없다는 것이다

  • PutField getPutField 필드를 사용한 암호화


    원리:
  • 1: 서열화할 때 JVM이 대상의 writeObject () readObject () 방법을 호출하려고 시도할 때 (자신의 사유화 실현 허용)
  • 2: 기본적으로 Object OutputStream의defaultWrite Object 방법과 ObjectInputStream의defaultReadObject 방법
  • 을 호출합니다
    private void writeObject(ObjectOutputStream out) {
            try {
                PutField putFields = out.putFields(); //  
                System.out.println("   :" + password);
                password = "encryption";//     
                putFields.put("password", password);
                System.out.println("      " + password);
                out.writeFields();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        private void readObject(ObjectInputStream in) {
            try {
                GetField readFields = in.readFields();
                Object object = readFields.get("password", "");
                System.out.println("       :" + object.toString());
                password = "pass";//     ,         
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
     //           out writeObject(),  in readObject()   

     

    시리얼화된 스토리지 규칙


     
  • 같은 대상에 대해 두 번 파일을 쓰고 첫 번째는 실제 대상의 서열화된 데이터를 쓰고 두 번째는 같은 대상의 인용 데이터를 쓴다.(즉, 동일한 객체를 가리킵니다.)
  • 1: 디스크 스토리지 공간 절약
  • 2: 반서열화된 데이터의 값은 처음 저장된 데이터의 값이어야 한다

  •  
    ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("result.obj")); Test test = new Test(); test.i = ;//유효한 out.writeObject(test); out.flush(); test.i = ;//무효 두 번째 반서열화는 대상의 인용 관계만 같은 인용 대상으로 표시하고 디스크 공간out을 절약합니다.writeObject(test); out.close(); ObjectInputStream oin = new ObjectInputStream(new FileInputStream( "result.obj")); Test t = (Test) oin.readObject(); Test t = (Test) oin.readObject(); System.out.println(t.i);//System.out.println(t.i);//

    Serializable 인터페이스의 정의:


     
     public interface Serializable {} //                ,   JVM             ,           !                 ?

     
    태그의 특정 정의 영역:
    writeObject0 메서드에는 다음과 같은 코드가 있습니다.
    if (obj instanceof String) {
     2                writeString((String) obj, unshared);
     3            } else if (cl.isArray()) {
     4                writeArray(obj, desc, unshared);
     5            } else if (obj instanceof Enum) {
     6                writeEnum((Enum>) obj, desc, unshared);
     7            } else if (obj instanceof Serializable) {
     8                writeOrdinaryObject(obj, desc, unshared);
     9            } else {
    10                if (extendedDebugInfo) {
    11                    throw new NotSerializableException(
    12                        cl.getName() + "/n" + debugInfoStack.toString());
    13                } else {
    14                    throw new NotSerializableException(cl.getName());
    15                }
    16            }

    이를 통해 알 수 있듯이 서열화 작업을 할 때 서열화될 클래스가 Enum, Array, Serializable 유형인지 판단하고, 그렇지 않으면 NotSerializable Exception을 던집니다.
     

    ArrayList 분석

  • 서열화를 실현하려면 반드시 Serializable 인터페이스를 실현해야 한다.ArrayList도 이 인터페이스를 실현했다
  • transient Object[] elementData;//ArrayList가 데이터를 저장하는 구조를 왜 버려야 합니까?답:Array List는 실제적으로 동적 수조로 매번 가득 채운 후에 자동으로 증가하는 길이를 설정합니다. 만약에 수조가 자동으로 증가하는 길이를 100으로 설정하고 실제적으로 원소 하나만 넣으면 99개의null 원소를 서열화합니다.서열화할 때 이렇게 많은null을 동시에 서열화하지 않도록 Array List는 원소 수조를transient로 설정합니다.
  • -* 구현 전략:
  • Array List는 write Object readObject 방법을 다시 쓰고 NULL 값 데이터를 필터합니다

    구체적 분석:


     
    ArrayList에서 writeObject와readObject 방법을 정의했습니다
    private void readObject(java.io.ObjectInputStream s)
     2        throws java.io.IOException, ClassNotFoundException {
     3        elementData = EMPTY_ELEMENTDATA;
     4        // Read in size, and any hidden stuff
     5        s.defaultReadObject();
     6        // Read in capacity
     7        s.readInt(); // ignored
     8        if (size > 0) {
     9            // be like clone(), allocate array based upon size not capacity
    10            ensureCapacityInternal(size);
    11            Object[] a = elementData;
    12            // Read in all elements in the proper order.
    13            for (int i=0; i) {
    14                a[i] = s.readObject();
    15            }
    16        }
    17    }

     
    private void writeObject(java.io.ObjectOutputStream s)
     2        throws java.io.IOException{
     3        // Write out element count, and any hidden stuff
     4        int expectedModCount = modCount;
     5        s.defaultWriteObject();
     6        // Write out size as capacity for behavioural compatibility with clone()
     7        s.writeInt(size);
     8        // Write out all elements in the proper order.
     9        for (int i=0; i) {
    10            s.writeObject(elementData[i]);
    11        }
    12        if (modCount != expectedModCount) {
    13            throw new ConcurrentModificationException();
    14        }
    15    }

    요약사용자 정의 서열화 및 반서열화 정책을 writeObject와readObject 방법으로 다시 쓰는 방법
     
    이 두 가지 방법은 어떻게 호출되었습니까?
    void invokeWriteObject(Object obj, ObjectOutputStream out)
     2        throws IOException, UnsupportedOperationException
     3    {
     4        if (writeObjectMethod != null) {
     5            try {
     6                writeObjectMethod.invoke(obj, new Object[]{ out });
     7            } catch (InvocationTargetException ex) {
     8                Throwable th = ex.getTargetException();
     9                if (th instanceof IOException) {
    10                    throw (IOException) th;
    11                } else {
    12                    throwMiscException(th);
    13                }
    14            } catch (IllegalAccessException ex) {
    15                // should not occur, as access checks have been suppressed
    16                throw new InternalError(ex);
    17            }
    18        } else {
    19            throw new UnsupportedOperationException();
    20        }
    21    }

    여기서 writeObjectMethod.invoke(obj, new Object[]{ out }); 관건입니다. 반사하는 방식으로 writeObjectMethod 방법을 호출합니다.공식적으로는 이 write Object Method를 이렇게 설명한다.
    class-defined writeObject method, or null if none
    우리의 예에서, 이 방법은 바로 우리가 Array List에서 정의한 write Object 방법이다.반사 방식을 통해 호출되었다
    그럼 어떻게 반사되는 거예요?
    Object StreamClass 이 방법에는 다음과 같은 코드가 있습니다:read Object Method read Object NoData Method는
                        if (externalizable) {
                            cons = getExternalizableConstructor(cl);
                        } else {
                            cons = getSerializableConstructor(cl);
                            writeObjectMethod = getPrivateMethod(cl, "writeObject",
                                new Class>[] { ObjectOutputStream.class },
                                Void.TYPE);
                            readObjectMethod = getPrivateMethod(cl, "readObject",
                                new Class>[] { ObjectInputStream.class },
                                Void.TYPE);
                            readObjectNoDataMethod = getPrivateMethod(
                                cl, "readObjectNoData", null, Void.TYPE);
                            hasWriteObjectData = (writeObjectMethod != null);
                        }
                        domains = getProtectionDomains(cons, cl);
                        writeReplaceMethod = getInheritableMethod(
                            cl, "writeReplace", null, Object.class);
                        readResolveMethod = getInheritableMethod(
                            cl, "readResolve", null, Object.class);
                        return null;
                    }

    좋은 웹페이지 즐겨찾기