2012-02-13 4 views
2

정수 foo가 포함 된 직렬화 된 개체 MyObject가 있습니다. 정수 foo에 10을 설정하고 writeObject()를 사용하여 객체를 파일에 저장합니다.Java 직렬화 설정 기본값 방지

개체 MyObject에 정수 막대를 추가합니다. 정수 막대에 값 15를 설정하고 readObject()를 사용하여 이전 직렬화 된 파일을로드합니다.

이전 직렬화 가능 파일에 정수 막대가 포함되지 않으므로 정수 막대의 값이 0이됩니다. 이전 직렬화 가능 파일에 가변 막대가없는 경우 값을 15로 유지하고 싶습니다.

readObject()를 오버라이드해야합니까? 아니면 readObject()가 "기본값"을 알 수없는 객체로 설정하지 못하게 할 수 있습니까?

생성자에서 자신의 기본값을 설정하고 내 자신의 기본값을 사용하여 버전 관리를 제어하기 때문에이 작업을 수행하려고합니다.

답변

1

직렬화는 기본값을 설정하지 않고 Java의 기본값 초기화 체계를 사용합니다.

질문을 요약 할 수 있다면. 직렬화가 스트림의 내용을 메모리의 값과 병합하려고합니다. 자바 직렬화에서는 생성 할 객체를 제어하기 때문에 불가능합니다. 직렬화 된 객체를 읽고 병합 할 필드를 병합하기위한 코드를 직접 작성할 수 있습니다. 자바 직렬화에 머물렀다면 (내가 당신이라면 분명히 알려줄 것입니다.) 계속 사용하고 싶다고합시다.

public class MyObject { 

    public void merge(MyObject that) { 
     // given some other instance of an object merge this with that. 
     // write your code here, and you can figure out the rules for which values win. 
    } 
} 

ObjectInputStream stream = new ObjectInputStream(new FileInputStream(file)); 
MyObject that = stream.readObject(); 
someObject.merge(that); 

비올라에서 어떤 필드를 someObject로 병합 할지를 제어합니다. 라이브러리가이 병합을 수행하기를 원하는 경우 http://flexjson.sourceforge.net을 확인하십시오. JSON 직렬화를 사용하며 POJO가 아닌 Bean에서 작동합니다. 그러나 이미 채워진 객체를 가져 와서 JSON 스트림의 값을 덮어 쓰는 방법이 있습니다. 이것에는 한계가 있습니다. 이것의 또 다른 이점은 객체 구조가 Java 직렬화가 기술적으로 할 수있는 것이 변경되었지만 실제로는 스트림을 읽을 수 있다는 것입니다.하지만 매우 어렵습니다.

+0

감사합니다. 좋은 답변입니다. 나는 직렬화에 매달 리지 않아서 다행이다. 대신에 무엇을 제안 하시겠습니까? 개체를 파일로 저장하고 좋은 버전 제어가 필요한 방법이 필요합니다. – Mikuz

+0

장기 저장 장치가 목표 인 경우 flexjson과 같은 것을 사용하는 것이 좋습니다. 원하는 오브젝트 구조를 사용하여 언제든지 데이터를 다시 읽을 수 있습니다. Java 직렬화는 객체와 패키지 구조가 동일하지 않은 경우 훨씬 더 어려워지고 불가능합니다.Java 직렬화를 장기간 스토리지에 사용하려고 시도 할 때마다 나는 그것을 제거하고 대체하게됩니다. – chubbsondubs

+0

발견 된 XStream은 매우 유용합니다. – Mikuz

0

transient 키워드를 사용하면 직렬화/역 직렬화에서 필드를 제외 할 수 있습니다.

+0

술집을 직렬화하고 비 직렬화하고 싶습니다. deserialize 된 컨텐트에 막대가 없으면 기본 deserialization 값을 적용하지 않을 것입니다. – Mikuz

+0

@ user1207523, 그런 논리를'readObject' 메쏘드 (또는'readResolve()')에 구현하기 만하면됩니다. – mre

0

MyObject에 다음 메소드를 추가하면 어떻게됩니까?

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException 
{ 
    bar = 15; // Set a default value of 15 if it's not in the serialized output file 
    ois.defaultReadObject(); 
} 
+0

실제로는 읽기에서 재정의됩니다. 바는 0이 될 수 없기 때문에이 기능이 작동합니다. ois.defaultReadObject(); if (bar == 0) bar = 15; 고맙습니다. 그래도 우리가 더 좋은 대답을 찾을 수 있기를 바랍니다. – Mikuz

+0

흥미 롭습니다. 나는 여기에 정의되지 않은 행동 (매우 가능)에 의존하거나 당신과 다른 무언가를하고있다. 내 테스트에서 (내 클래스에 막대를 추가하기 전에 직렬화 된 객체 파일을 사용하여) 읽기가 값을 무시하지 않고 결국 15를 얻게됩니다. 내 직렬화 된 개체 파일에 첫 번째 위치에 막대가 포함 된 경우에만이를 재정의합니다. 바라기를 당신은 더 나은 대답을 찾을 수 있습니다. – spdaley