Java의 SerialVersionUID

Sheeraz Gul 2023년10월12일
Java의 SerialVersionUID

이 튜토리얼은 Java에서 SerialVersionUID를 사용하는 방법을 보여줍니다.

Java의 ‘SerialVersionUID’

SerialVersionUID는 직렬화에 사용됩니다. 직렬화는 개체를 바이트 스트림으로 변환하여 데이터를 저장하고 어딘가로 보내는 프로세스이고 역직렬화는 그 반대 프로세스입니다.

직렬화 프로세스 중에 Java 런타임은 버전 번호를 각 Serializable 클래스와 연결합니다. 그 번호는 SerialVersionUID라고 합니다.

SerialVersionUID는 직렬화된 데이터의 발신자와 수신자가 해당 데이터에 대한 클래스를 로드했으며 직렬화 측면에서 호환되는지 확인하는 데 사용됩니다.

예를 들어 수신자가 해당 발신자의 클래스와 다른 SerialVersionUID를 사용하여 개체에 대한 클래스를 로드한 경우 InvalidClassException이 발생합니다.

Serializable 클래스에 대한 SerialVersionUID를 선언할 수 있습니다. SerialVersionUIDStatic FinalLong 유형으로 선언됩니다.

구문을 참조하십시오.

private static final long serialVersionUID = 10L;

SerialVersionUID를 사용하여 직렬화 및 역직렬화를 구현하는 예제를 시도해 봅시다. 예를 참조하십시오:

package delftstack;

import java.io.*;
import java.util.logging.Logger;

public class Example implements java.io.Serializable {
  // The Default serial version uid
  private static final long serialVersionUID = 4L;
  // random name
  private static final String File_Name = "ExampleClassBytes.ser";
  private static final Logger logger_File = Logger.getLogger("");
  // Few data fields Which will be able to serialize
  private static String Static_Variable;
  private int Integer_Variable;

  // Few data fields Which will not be able to serialize
  transient private String Transient_Variable = "this is a transient instance field";
  private Thread Thread_Class;

  private static Object readIn() throws IOException, ClassNotFoundException {
    ObjectInputStream Object_Input_Stream =
        new ObjectInputStream(new FileInputStream(new File(File_Name)));
    return Object_Input_Stream.readObject();
  }

  private static void writeOut(java.io.Serializable object) throws IOException {
    ObjectOutputStream Object_Output_Stream =
        new ObjectOutputStream(new FileOutputStream(new File(File_Name)));
    Object_Output_Stream.writeObject(object);
    Object_Output_Stream.close();
  }

  @Override
  public String toString() {
    return "Example Class:- final static fileName is: " + File_Name + ", final static logger is: "
        + logger_File + ", the non-final static staticVariable is: " + Static_Variable
        + ", the instance intVariable is: " + Integer_Variable
        + ", the transient instance Variable is: " + Transient_Variable
        + ", the non-serializable instance field threadClass is : " + Thread_Class;
  }

  public static void main(String[] args) throws IOException, ClassNotFoundException {
    // Serialization

    Example Demo = new Example();
    Demo.Integer_Variable = 1;
    Static_Variable = "this is the static variable";
    writeOut(Demo);
    System.out.println("Example Class to be saved: " + Demo);

    // De-serialization

    System.out.println("Example Class deserialized: " + readIn());
  }
}

Serializable 클래스가 SerialVersionUID를 명시적으로 선언하지 않으면 런타임은 측면을 기반으로 해당 클래스의 기본 SerialVersionUID를 계산합니다. 이제 위 코드의 출력을 봅시다.

Example Class to be saved: Example Class:- final static fileName is: ExampleClassBytes.ser, final static logger is: java.util.logging.LogManager$RootLogger@27973e9b, the non-final static staticVariable is: this is the static variable, the instance intVariable is: 1, the transient instance Variable is: this is a transient instance field, the non-serializable instance field threadClass is : null
Example Class deserialized: Example Class:- final static fileName is: ExampleClassBytes.ser, final static logger is: java.util.logging.LogManager$RootLogger@27973e9b, the non-final static staticVariable is: this is the static variable, the instance intVariable is: 1, the transient instance Variable is: null, the non-serializable instance field threadClass is : null

위의 시나리오를 기반으로 SerialVersionUID에 대한 몇 가지 중요한 사항:

  1. 정적 및 일시적 필드는 직렬화 중에 무시되며 역직렬화 후에는 일시적 및 비정적 최종 필드가 null이 됩니다.
  2. 직렬화를 위해서는 IOException을 처리해야 하고 역직렬화를 위해서는 IOExceptionClassNotFoundException을 처리해야 합니다. 이는 역직렬화된 클래스 유형이 클래스 경로에 있어야 함을 의미합니다.
  3. ObjectInputStream.readObject()ObjectOutputStream.writeObject(object) 메서드는 직렬화 및 역직렬화 작업에 사용됩니다.
  4. 직렬화 및 역직렬화는 개체를 복제 및 복사하는 데 사용할 수 있으며 일반 복제 작업보다 비교적 느립니다.
  5. 초기화되지 않은, 직렬화할 수 없는, 일시적이지 않은 인스턴스가 허용됩니다.
  6. java.io.Serializable을 구현하는 클래스를 수정하는 동안 클래스에 SerialVersionUID가 없으면 컴파일러에서 SerialVersionUID를 생성하므로 주의해야 합니다.
  7. SerialVersionUID 계산은 필드뿐만 아니라 생성자, 구현 절 등과 같은 다른 측면을 기반으로 합니다. 즉, 이전 버전과의 호환성도 유지하는 SerialVersionUID를 명시적으로 선언해야 합니다.
작가: Sheeraz Gul
Sheeraz Gul avatar Sheeraz Gul avatar

Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.

LinkedIn Facebook