serialVersionUID 명시적 설정 이유

LinkinPark·2024년 7월 23일

개요

singletonList()를 까보다가 serialVersionUID 상수를 발견했다.

대충 어떤 역할을 하고 직렬화/역직렬화할 때 버전관리에 중요한 역할을 하는지는 알고 있었지만, 정리가 안된느낌이였다.

정리를 해보자.

serialVersionUID

serialVersionUID란?

Java에서 직렬화(serialization)와 역직렬화(deserialization) 과정에서 클래스의 버전 관리를 위해 사용하는 고유한 식별자이다.

직렬화 / 역직렬화

직렬화는 객체의 상태를 바이트 스트림으로 변환하여 파일에 저장하거나 네트워크를 통해 전송할 수 있도록 하는 과정이고, 역직렬화는 그 바이트 스트림을 다시 객체로 복원하는 과정이다.

즉, 직렬화 역직렬화는 객체에서 바이트 스트림으로, 바이트 스트림에서 객체로 변환하는 과정이라고 볼 수 있다.

serialVersionUID의 역할

serialVersionUID는 직렬화된 객체와 클래스의 버전을 확인하는 데 사용된다.
역직렬화 과정에서 serialVersionUID를 비교하여 직렬화된 객체와 현재 클래스의 버전이 일치하는지 확인한다.
만약 일치하지 않으면 InvalidClassException이 발생한다.

버전관리

버전관리는 이전 버전 클래스와 새로운 버전 클래스간 호완성을 관리하는 방법이다.

예를 들어 클래스의 필드나 메서드가 변경될 경우, serialVersionUID도 변경되어야 한다.
이를 통해 이전 버전의 클래스와 새로운 버전의 클래스 간의 호환성을 관리할 수 있다.

예시

import java.io.Serializable;

public class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

    // 생성자, getter, setter 등
}

만약 해당 객체에 serialVersionUID를 명시적으로 설정하지 않더라도, 컴파일러가 클래스 내부 구조를 기반으로 자동생성한다.

하지만 이는 클래스 변경에 민감하게 반응하여 사소한 변경에도 다른 값이 생성될 수 있다.

그럼 명시적으로 위와같이 설정하면, 클래스 변경에 대한 버전 관리를 명확하게 할 수 있다.
이렇게 하면 클래스가 변경되더라도 serialVersionUID를 유지할 수 있으며, 의도적으로 호환성을 유지할 수 있다.

class Person implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private int age;
    private String address; // 새로운 필드 추가

    public Person(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }
}

이렇게 변경하더라도, 명시적으로 serialVersionUID를 설정한다면 InvalidClassException이 발생하지 않는다.
클래스 구조가 변경되더라도 직렬화된 객체와 호환성을 유지할 수 있게된다.

serialVersionUID 미지정했다면?
자동으로 생성된 serialVersionUID는 클래스가 변경될 때마다 달라지므로, 직렬화된 객체와 현재 클래스의 버전이 다르면 InvalidClassException이 발생한다.

결론

serialVersionUID은 객체 변경사항에 대한 호환성을 유지하기 위해 명시적으로 설정한다.

profile
It's work, but touch it

0개의 댓글