HOWTO · Java
Java의 SerialVersionUID
이 자습서는 Java에서 SerialVersionUID를 사용하는 방법을 보여줍니다.
이 페이지의 내용
이 튜토리얼은 Java에서 SerialVersionUID를 사용하는 방법을 보여줍니다.
Java의 ‘SerialVersionUID’
SerialVersionUID는 직렬화에 사용됩니다. 직렬화는 개체를 바이트 스트림으로 변환하여 데이터를 저장하고 어딘가로 보내는 프로세스이고 역직렬화는 그 반대 프로세스입니다.
직렬화 프로세스 중에 Java 런타임은 버전 번호를 각 Serializable 클래스와 연결합니다. 그 번호는 SerialVersionUID라고 합니다.
SerialVersionUID는 직렬화된 데이터의 발신자와 수신자가 해당 데이터에 대한 클래스를 로드했으며 직렬화 측면에서 호환되는지 확인하는 데 사용됩니다.
예를 들어 수신자가 해당 발신자의 클래스와 다른 SerialVersionUID를 사용하여 개체에 대한 클래스를 로드한 경우 InvalidClassException이 발생합니다.
Serializable 클래스에 대한 SerialVersionUID를 선언할 수 있습니다. SerialVersionUID는 Static Final 및 Long 유형으로 선언됩니다.
구문을 참조하십시오.
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에 대한 몇 가지 중요한 사항:
- 정적 및 일시적 필드는 직렬화 중에 무시되며 역직렬화 후에는 일시적 및 비정적 최종 필드가 null이 됩니다.
- 직렬화를 위해서는
IOException을 처리해야 하고 역직렬화를 위해서는IOException및ClassNotFoundException을 처리해야 합니다. 이는 역직렬화된 클래스 유형이 클래스 경로에 있어야 함을 의미합니다. ObjectInputStream.readObject()및ObjectOutputStream.writeObject(object)메서드는 직렬화 및 역직렬화 작업에 사용됩니다.- 직렬화 및 역직렬화는 개체를 복제 및 복사하는 데 사용할 수 있으며 일반 복제 작업보다 비교적 느립니다.
- 초기화되지 않은, 직렬화할 수 없는, 일시적이지 않은 인스턴스가 허용됩니다.
java.io.Serializable을 구현하는 클래스를 수정하는 동안 클래스에SerialVersionUID가 없으면 컴파일러에서SerialVersionUID를 생성하므로 주의해야 합니다.SerialVersionUID계산은 필드뿐만 아니라 생성자, 구현 절 등과 같은 다른 측면을 기반으로 합니다. 즉, 이전 버전과의 호환성도 유지하는SerialVersionUID를 명시적으로 선언해야 합니다.