2013-10-03 1 views
0

개체를 serialize하고 네트워크를 통해 전송합니다. 직렬화 된 클래스 개체에는 내가 정의한 serilizableId가 있습니다. 다른 JVM에서는 SeriliazibleId를 동일하게 유지하지만 일부 특성은 변경합니다. 어떤 일이 일어날 것이며 왜 그럴까요? 역 직렬화 할 수 있습니까?SerializationVersionId가 같지만 클래스가 수정 되었습니까?

+2

아직 사용해 보지 않으셨습니까? – Vulcan

+0

동일한 번호를 유지하면 작동하지 않습니다. 쓰고 읽는 데이터는 동일해야합니다. –

답변

1

Java Object Serialization Specification here을 참조하십시오. 당신이 는 할 수 없습니다 어떤 특정한에서

:

  • 삭제 필드 - 필드는 클래스에서 삭제 된 경우, 그 값을 포함하지 않습니다 기록 스트림. 이전 클래스에서 스트림을 읽을 때 스트림에서 값을 사용할 수 없으므로 필드 값이 기본값으로 설정됩니다. 그러나이 기본값은 계약을 이행하기위한 이전 버전의 능력을 저하시킬 수 있습니다.
  • 계층 구조를 위 또는 아래로 이동 - 스트림의 데이터가 잘못된 순서로 나타나기 때문에 허용 할 수 없습니다.
  • 비 정적 필드를 정적 또는 비 transient 필드로 변경 - 기본 직렬화를 사용하는 경우이 변경은 클래스에서 필드를 삭제하는 것과 같습니다. 이 버전의 클래스는 해당 데이터를 스트림에 쓰지 않으므로 이전 버전의 클래스에서 읽을 수 없습니다. 필드를 삭제할 때와 마찬가지로 이전 버전의 필드가 기본값으로 초기화되므로 예기치 않은 방식으로 클래스가 실패 할 수 있습니다.
  • 기본 필드의 선언 된 유형 변경 - 클래스의 각 버전은 선언 된 유형으로 데이터를 씁니다. 스트림의 데이터 유형이 필드의 유형과 일치하지 않으므로 필드를 읽으려고 시도하는 이전 버전의 클래스가 실패합니다.
  • writeObject 또는 readObject 메소드가 더 이상 기본 필드 데이터를 쓰거나 읽지 않도록 변경하거나 이전 필드 버전을 작성하지 않았을 때 읽기 또는 쓰기를 시도하도록 변경합니다. 기본 필드 데이터는 일관되게 스트림에 나타나거나 나타나지 않아야합니다.
  • 클래스가 사용 가능 클래스의 구현과 호환되지 않는 데이터를 포함하기 때문에 클래스를 Serializable에서 Externalizable 또는 그 반대로 변경하는 것은 호환되지 않는 변경 사항입니다.
  • 스트림에 사용 가능한 클래스의 구현과 호환되지 않는 데이터가 포함되므로 클래스를 비 enum 유형에서 enum 유형으로 또는 그 반대로 변경하십시오.
  • Serializable 또는 Externalizable 중 하나를 제거하면 호환되지 않는 변경 사항이 생깁니다.이 클래스는 이전 버전의 클래스에서 필요했던 필드를 더 이상 제공하지 않으므로 호환되지 않습니다.
  • 이전 버전의 클래스와 호환되지 않는 객체를 생성하는 경우 클래스에 writeReplace 또는 readResolve 메소드를 추가하면 호환되지 않습니다. 재구성되는 클래스는 스트림에서 발생하지 않는 필드가 객체에 해당 필드가 초기화됩니다 - 필드를 추가

    • 가 : 당신이 대신 할 수 있습니다 무엇

    유형에 대한 기본값. 클래스 고유의 초기화가 필요한 경우, 클래스는 필드를 기본값 이외의 값으로 초기화 할 수있는 readObject 메서드를 제공 할 수 있습니다.

  • 클래스 추가 - 스트림에는 스트림의 각 객체에 대한 유형 계층 구조가 포함됩니다.스트림의이 계층 구조를 현재 클래스와 비교하면 추가 클래스를 감지 할 수 있습니다. 스트림에 객체를 초기화 할 정보가 없기 때문에 클래스의 필드는 기본값으로 초기화됩니다.
  • 클래스 제거 - 스트림의 클래스 계층 구조를 현재 클래스의 클래스 계층 구조와 비교하면 클래스가 삭제되었음을 감지 할 수 있습니다. 이 경우 해당 클래스에 해당하는 필드 및 객체가 스트림에서 읽습니다. 원시적 필드는 파기됩니다 만, 삭제 된 클래스에 의해 참조되는 객체는 나중에 스트림에서 참조 될 수 있기 때문에 작성됩니다. 스트림이 가비지 수집되거나 재설정 될 때 가비지 수집됩니다.
  • writeObject/readObject 메서드 추가 - 스트림을 읽는 버전에 이러한 메서드가있는 경우 readObject는 기본 직렬화에 의해 스트림에 기록 된 필수 데이터를 읽는 것이 일반적입니다. 선택적 데이터를 읽기 전에 먼저 defaultReadObject를 호출해야합니다. writeObject 메소드는 평소처럼 defaultWriteObject를 호출하여 필요한 데이터를 쓰고 선택적 데이터를 쓸 수 있습니다.
  • writeObject/readObject 메서드 제거 - 스트림을 읽는 클래스에 이러한 메서드가없는 경우 필수 데이터는 기본적으로 serialization을 통해 읽혀지고 선택적 데이터는 무시됩니다.
  • java.io.Serializable 추가하기 - 이것은 유형을 추가하는 것과 같습니다. 이 클래스의 스트림에는 값이 없기 때문에 필드가 기본값으로 초기화됩니다. 직렬화 할 수없는 클래스의 서브 클래스를 지원하려면 클래스의 상위 유형에 인수가없는 생성자가 있어야하고 클래스 자체가 기본값으로 초기화되어야합니다. 인수가없는 생성자를 사용할 수 없으면 InvalidClassException이 throw됩니다.
  • 필드에 대한 액세스 변경 - 액세스 수정 자 public, package, protected 및 private은 값을 필드에 할당하는 직렬화 기능에 영향을주지 않습니다.
  • 필드를 static에서 nonstatic 또는 transient에서 nontransient로 변경 - 기본 직렬화를 사용하여 직렬화 가능 필드를 계산할 때이 변경은 클래스에 필드를 추가하는 것과 같습니다. 새 필드는 스트림에 기록되지만 직렬화는 정적 또는 일시적인 필드에 값을 할당하지 않으므로 이전 클래스는 값을 무시합니다.
0

당신이 당신의 클래스에 대한 private static final long serialVersionUID;를 사용하는 경우, 당신은 그들이 호환이 가능 때까지 모든 버전의 변경, 클래스의 직렬화 복원에 영향을 미치지것이라는 점을 확인하고 있습니다. 이전 버전과 호환되지 않는 경우 직렬 버전 ID를 증가시켜야합니다.

관련 문제