2012-04-29 3 views
1

A, B 및 C 유형의 객체가 있다고 가정 해 봅시다. 각각 A, B 및 C의 모든 인스턴스를 포함하는 3 개의지도가 있습니다. 내부적으로 A와 B는 모두 C의지도를 가지고 있습니다. 언제든지 응용 프로그램의 상태를 저장하고 복원 할 수 있기를 원합니다.Java에서 관련 객체의 직렬화

오늘까지 필자는 항상 필자에게 피라미드 형 응용 프로그램을 직렬화하여 최상위 개체에서 serialize를 호출하고 호출을 다른 모든 항목에 전파했습니다. 이 상황을 어떻게 처리합니까? A map에서 serialize를 호출 한 다음 B map에서 serialize를 호출하면 C 인스턴스가 두 번 저장되지 않습니까? 그럴 경우에도 A deserialize 후에 B map을 deserialize 할 때 C 인스턴스를 덮어 쓰는 것처럼 비 직렬화가 응용 프로그램 상태를 유지합니까? 사전에

감사합니다.

답변

4

Java 직렬화 메커니즘은 동일한 객체에 대한 다중 참조를 알고 있으며 복제하지 않습니다. 개체는 한 번 저장되고 모든 내부 참조는 유지됩니다.

역 직렬화 후 개체의 상태는 동일하지만 하나의 인스턴스와 해당 개체에 대한 여러 참조가 있습니다.

+0

내가 다음을 수행해야하는 방법, 동일의 OutputStream에 모두 A와 B의지도를 쓰기? 서로 다른 스트림 (내 경우에는 파일)에 하나씩 쓴 다음 동일한 (또는 다른) 순서로 복원하면 어떻게됩니까? – bluehallu

+0

하나의 단일 개체에 넣고 해당 개체를 직렬화하십시오. 아마도 가장 간단한 방법 일 것입니다. –

1

가장 좋은 방법은지도를 단일 개체에 저장하고이 개체를 serialize하여 "피라미드 형"모델로 돌아가는 것입니다.

public class ApplicationState implements Serializable { 
    private Map<Foo, A> aMap; 
    private Map<Bar, B> bMap; 
} 

직렬화 메커니즘은 동일한 개체의 그래프와 여러 인스턴스를 아무런 문제없이 처리합니다.

+0

문제는 A와 B를 같은 장소에 놓을 수 없다는 것입니다. 더 쉽게 작업을 수행 할 수 있습니다. – bluehallu

3

ObjectOutputStream에 writes의 자바 독 : writeObject 메소드는 스트림 오브젝트를 작성하기 위해 사용된다

. 문자열 및 배열을 포함한 모든 객체는 writeObject로 기록됩니다. 여러 객체 또는 프리미티브를 스트림에 쓸 수 있습니다. 오브젝트는, 기입해진 순서와 같은 형태로, 대응하는 ObjectInputstream로부터 읽어 들일 필요가 있습니다. (일시적 또는 정적 필드를 제외한) 다른 개체

참조는 그 개체가 또한 기록되도록. 단일 객체에 대한 다중 참조는 참조 공유 메커니즘을 사용하여 인코딩되므로 원본 그래프를 작성했을 때와 동일한 모양으로 객체의 그래프를 복원 할 수 있습니다.

특히 동일한 객체가 ObjectOutputStream에 반복적으로 쓰여지는 경우 해당 데이터는 한 번만 기록됩니다.

다음과 같은 프로그램을 실행하여 확인할 수 있습니다

class A implements Serializable { 
    C c; 
} 

class B implements Serializable { 
    C c; 
} 

class C implements Serializable { 

} 

public class Test { 

    public static void main(String[] args) throws Exception { 
     C c = new C(); 

     A a = new A(); 
     a.c = c; 

     B b = new B(); 
     b.c = c; 


     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     try (ObjectOutputStream oos = new ObjectOutputStream(baos)) { 
      oos.writeObject(a); 
      oos.writeObject(b); 
      oos.writeObject(c); 
     } 
     byte[] data = baos.toByteArray(); 

     try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))) { 
      A newA = (A) ois.readObject(); 
      B newB = (B) ois.readObject(); 
      C newC = (C) ois.readObject(); 

      System.out.println(newA.c == newC && newB.c == newC); // prints "true" 
     } 
    } 
} 
+0

그래서 단일 출력 스트림에서 작동합니다. 이제지도를 파일로 직렬화하고 B를 다른 파일로 매핑 한 다음 둘 다 복원하면됩니까? – bluehallu