Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java 직렬화에서 transient 키워드의 작동 원리 완벽 정리

Java에서 직렬화(Serialization)는 객체의 상태를 바이트 스트림(byte stream)으로 변환하여 네트워크를 통해 전송할 수 있도록 하는 핵심 개념입니다. JPA나 RMI 같은 기술들이 내부적으로 이 직렬화 메커니즘을 활용하고 있습니다.

transient 변수란 무엇인가?

transient(일시적) 키워드로 선언된 변수는 직렬화 과정에서 완전히 제외됩니다. 즉, 변수를 transient로 선언하면 그 값은 바이트 스트림에 저장되지 않으며, 역직렬화(de-serialization) 이후에는 항상 기본값(null, false, 또는 0)으로 초기화됩니다.

따라서 객체를 직렬화할 때 특정 인스턴스 변수를 JVM이 무시하도록 하고 싶다면, 해당 변수를 transient로 선언하면 됩니다.

public transient int limit = 55; // 직렬화되지 않음 (저장 안 됨)
public int b; // 정상적으로 직렬화됨

예제 코드

다음 Java 프로그램에서 Student 클래스는 name과 age 두 개의 인스턴스 변수를 가지고 있으며, age는 transient로 선언되어 있습니다. 다른 클래스인 SerializeExample에서는 Student 객체를 직렬화한 후 역직렬화하여 각 인스턴스 변수의 값을 화면에 출력합니다.

age가 transient로 선언되어 직렬화 대상에서 제외되었기 때문에, 역직렬화된 객체에서는 name 값만 유지되고 age는 기본값인 0으로 출력됩니다.

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Student implements Serializable {
    private String name;
    private transient int age;
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public void display() {
        System.out.println("Name: "+this.name);
        System.out.println("Age: "+this.age);
    }
}
public class SerializeExample {
    public static void main(String args[]) throws Exception {
        // Student 객체 생성
        Student std = new Student("Sarmista", 27);
        // 객체 직렬화
        FileOutputStream fos = new FileOutputStream("e:\\student.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(std);
        oos.close();
        fos.close();
        System.out.println("Values before de-serialization: ");
        std.display();
        System.out.println("Object serialized.......");
        // 객체 역직렬화
        FileInputStream fis = new FileInputStream("e:\\student.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Student deSerializedStd = (Student) ois.readObject();
        System.out.println("Object de-serialized.......");
        ois.close();
        fis.close();
        System.out.println("Values after de-serialization");
        deSerializedStd.display();
    }
}

실행 결과

Values before de-serialization:
Name: Sarmista
Age: 27
Object serialized.......
Object de-serialized.......
Values after de-serialization
Name: Sarmista
Age: 0

결과 분석

실행 결과를 보면 직렬화 이전에는 age 값이 27로 출력되지만, 역직렬화 이후에는 0으로 출력되는 것을 확인할 수 있습니다. 이는 age 변수가 transient로 선언되어 직렬화 과정에서 제외되었기 때문입니다.

이처럼 transient 키워드는 비밀번호, 임시 계산 값 등 보안상 또는 논리적으로 저장할 필요가 없는 필드를 직렬화 대상에서 배제할 때 유용하게 사용됩니다.