문제

Eclipse에서 클래스가 직렬화 할 수있는 경우 두 가지 옵션이 있습니다. 기본값 추가 serialVersionUID(1L) 또는 생성 serialVersionUID(3567653491060394677L). 첫 번째는 더 시원하다고 생각하지만 여러 번 사람들이 두 번째 옵션을 사용하는 것을 보았습니다. 생성해야 할 이유가 있습니까? long serialVersionUID?

도움이 되었습니까?

해결책

내가 알 수있는 한, 그것은 이전 릴리스와의 호환성에만 해당됩니다. 이것은 이전에 SerialversionUid를 사용하지 않는 것을 무시하고 당신이 알고 있어야하는 변화를 한 경우에만 유용합니다. 호환 가능 그러나 직렬화가 깨지게됩니다.

참조 Java 직렬화 사양 자세한 사항은.

다른 팁

직렬화 버전 UID의 목적은 객체의 유효한 직렬화를 수행하기 위해 다른 버전의 클래스를 추적하는 것입니다.

아이디어는 특정 버전의 클래스에 고유 한 ID를 생성하는 것입니다. 그런 다음 새 필드와 같이 클래스에 추가 된 새 세부 사항이있을 때 변경됩니다.

항상 같은 ID를 사용합니다 1L 향후, 클래스 정의가 변경되면 직렬화 된 객체의 구조를 변경하게하는 경우 객체를 사로화하려고 할 때 문제가 발생할 가능성이 높습니다.

ID가 생략되면 Java는 실제로 객체 필드를 기반으로 귀하의 ID를 계산하지만 비싼 프로세스라고 생각하므로 수동으로 제공하면 성능이 향상됩니다.

다음은 클래스의 직렬화 및 버전화를 논의하는 기사에 대한 몇 가지 링크입니다.

생성 된 사람의 주된 이유는 이미 지속 된 사본이있는 기존 버전의 클래스와 호환되기 때문입니다.

"긴"기본값 serialVersionUID 에 의해 정의 된 기본값입니다 Java 직렬화 사양, 기본 직렬화 동작에서 계산됩니다.

따라서 기본 버전 번호를 추가하면 구조적으로 변경되지 않은 한 클래스 (DE-) 직렬화가 더 빠르지 만 클래스를 변경하면 (필드 추가/제거)도 업데이트해야합니다. 일련 번호.

기존 비트 스트림과 호환되지 않아도됩니다. 1L 변경할 때 필요에 따라 버전을 증가시킵니다. 즉, 변경된 클래스의 기본 직렬화 버전이 이전 클래스의 기본 버전과 다를 때.

당신은 구현하는 클래스를 정의 할 때마다 SerialversionUid를 절대적으로 만들어야합니다. java.io.Serializable. 그렇지 않으면 자동으로 당신을 위해 만들어 질 것이지만 이것은 나쁘다. 자동으로 생성 된 SerialversionUid는 클래스의 메소드 서명을 기반으로하므로 미래에 클래스를 변경하여 메소드 (예를 들어)를 추가하여 클래스의 "오래된"버전이 실패합니다. 일어날 수있는 일은 다음과 같습니다.

  1. SerialversionUid를 정의하지 않고 클래스의 첫 번째 버전을 만듭니다.
  2. 수업의 인스턴스를 지속적인 매장으로 일련 화하십시오. SerialversionUid가 자동으로 생성됩니다.
  3. 새로운 방법을 추가하려면 클래스를 수정하고 응용 프로그램을 재배치하십시오.
  4. 2 단계에서 직렬화 된 인스턴스를 제조하려고 시도했지만 이제는 자동 생성 된 SerialversionUid가 있기 때문에 실패합니다 (성공해야 할 때).

SerialversionUid를 지정하지 않으면 Java는 즉시 하나를 만듭니다. 생성 된 SerialversionUid는 그 숫자입니다. 클래스에서 클래스가 이전 직렬화 된 Verisons와 호환되지 않지만 해시를 변경하는 것을 변경하면 생성 된 매우 큰 수 SerialversionUid (또는 오류 메시지에서 "예상"번호)를 사용해야합니다. . 그렇지 않으면, 모든 것을 스스로 추적한다면, 0, 1, 2는 더 좋습니다.

SerialversionUid (3567653491060394677L)를 생성하는 대신 SerialversionUid (1L)를 사용하면 무언가를 말하고 있습니다.

당신은 당신이 버전 번호가 1 인이 클래스의 양립 할 수없는 직렬화 된 버전을 가진이 클래스를 터치하지 않는 시스템이 없다고 100% 확신한다고 말합니다.

직렬화 된 버전 이력이 알려지지 않은 것에 대한 변명을 생각할 수 있다면 자신감을 가지고 말하기 어려울 수 있습니다. 평생 동안 성공적인 수업은 많은 사람들이 유지하고 많은 프로젝트에 살며 많은 시스템에 거주합니다.

당신은 그것에 대해 고민 할 수 있습니다. 또는 잃기를 바라는 복권을 연주 할 수 있습니다. 버전을 생성하면 잘못 될 가능성이 약간 높습니다. 당신이 "이봐, 나는 아직 1을 사용하지 않았다고 생각한다"고 가정하면 당신의 확률은 작은 것보다 큽니다. 우리 모두가 0과 1이 시원하다고 생각하기 때문에 정확하게는 당신이 그들을 때릴 확률이 높다고 생각하기 때문입니다.

-

SerialversionUid (1L)를 사용하지 않고 SerialversionUID (3567653491060394677L)를 생성하면 무언가를 말하고 있습니다.

당신은 사람들 이이 클래스의 역사를 통해 다른 버전 번호를 수동으로 만들거나 생성했을 수 있으며, 오랫동안 큰 숫자를 괴롭 히기 때문에 신경 쓰지 않습니다.

어느 쪽이든, 당신은 그것이 존재하는 곳이나 존재하는 곳의 전체 우주에서 클래스를 직렬화 할 때 사용 된 버전 번호의 기록을 완벽하게 알지 않는 한, 당신은 기회를 얻고 있습니다. 당신이 100% 확실하게 1을 만들 시간이 있다면 1은 AOK입니다. 그것이 많은 일이라면, 계속해서 맹목적으로 숫자를 생성하십시오. 당신은 그 잘못을당하는 것보다 복권을 얻을 가능성이 더 높습니다. 그렇다면 알려 주시면 맥주를 사겠습니다.

복권 연주에 대한이 모든 이야기로 SerialversionUid가 무작위로 생성된다는 인상을 주었을 것입니다. 실제로 숫자의 범위가 오래된 값의 모든 가능한 모든 값에 대해 균등하게 분포되는 한. 그러나 실제로는이 방법으로 수행됩니다.

http://docs.oracle.com/javase/6/docs/platform/serialization/spec/class.html#4100

당신이 얻는 유일한 차이점은 당신이 무작위의 원천이 필요하지 않다는 것입니다. 클래스 자체의 변경 사항을 사용하여 결과를 변경합니다. 그러나 비둘기 구멍 원리에 따르면 여전히 잘못 될 수있는 기회가 여전히있을 가능성이 있습니다. 엄청나게 가능성이 높습니다. 그래서 나에게 맥주를 꺼내는 행운을 빕니다.

그러나 클래스가 하나의 시스템과 하나의 코드 기반에만 살아야하더라도, 수작업 숫자를 증분하면 충돌 가능성이 전혀 없다고 생각하면 인간을 이해하지 못한다는 것을 의미합니다. :)

SerialversionUid는 "정적 필드가 직렬화되지 않는다"는 규칙에 대한 예외입니다. ObjectOutputStream은 SerialVersionUid의 값을 출력 스트림에 할 때마다 기록합니다. ObjectInputStream은 그것을 다시 읽고 스트림에서 읽은 값이 현재 클래스의 현재 버전에서 SerialversionUid 값과 일치하지 않으면 InvalidClassexception을 던집니다. 또한, 클래스에 공식적으로 직렬화로 선언 된 SerialversionUid가없는 경우, 컴파일러는 클래스에서 선언 된 필드를 기반으로 생성 된 값으로 자동으로 추가합니다.

많은 경우 기본 ID가 고유하지 않기 때문입니다. 그래서 우리는 고유 한 개념을 만들기위한 ID를 만듭니다.

@David Schmitts 답변에 추가하려면, 일반적으로 기본 1L을 컨벤션에서 사용합니다. 나는 돌아가서 몇 번만 바뀌면서 몇 번만 바꿔야했지만, 변경을 할 때 기본 번호를 매번 하나씩 업데이트했을 때 알았습니다.

현재 회사에서는 자동 생성 번호가 필요하므로 컨벤션에 사용하지만 기본값을 선호합니다. 내 생각은, 당신이 일하는 컨벤션이 아니라면, 당신이 어떤 이유로 일련의 클래스의 구조를 끊임없이 바꾸지 않을 것이라고 생각하지 않는 한, 기본값을 사용하는 것입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top