
직렬화는 자바 객체를 바이트 스트림으로 변환하는 과정입니다. 이 과정 덕분에 객체를 파일로 저장하거나, 네트워크로 전송할 수 있습니다.
자바에서는 ObjectOutputStream 클래스를 사용하여 아래와 같이 직렬화를 수행합니다.
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
public class SerializationExample {
static class FileDto implements Serializable { // 반드시, Serializable 구현 필요
private static final long serialVersionUID = 1L; // 클래스 버전 관리 (역직렬화 시 호환성 보장)
private transient String password; // transient 키워드가 선언된 필드는 직렬화 제외 (static도 해당)
private String name;
private int size;
public FileDto(String name, int size) {
this.name = name;
this.size = size;
}
}
public static void main(String[] args) {
try {
// 직렬화 대상
FileDto dto = new FileDto("example.txt", 1024);
// 직렬화 수행
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.dat"));
// writeObject()는 자바 객체를 바이트 스트림으로 변환 후
// 해당 스트림을 연결된 출력 대상에 기록
// - 클래스 메타데이터, serialVersionUID 저장
// - transient, static은 제외
// - 참조 타입이 있을 경우, 재귀적으로 직렬화
oos.writeObject(dto);
oos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
static 변수는 왜 (역)직렬화하지 않나요?
static필드는 Method Area에서 관리되는 상태로, 인스턴스의 상태가 아닌 클래스 전체가 공유하는 상태입니다. 즉,static필드를 굳이 각 객체에 저장할 필요가 없다는 것을 의미합니다.
역직렬화는 바이트 스트림을 다시 자바 객체로 변환하는 과정입니다. 이 과정을 통해 파일이나 네트워크에서 받은 데이터를 원래의 객체 상태로 복원할 수 있습니다.
자바에서는 ObjectInputStream 클래스를 사용하여 아래와 같이 역직렬화를 수행합니다.
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;
public class DeserializationExample {
static class FileDto implements Serializable { // 반드시, Serializable 구현 필요
private static final long serialVersionUID = 1L; // 클래스 버전 관리 (역직렬화 시 호환성 보장)
private transient String password; // transient 키워드가 선언된 필드는 역직렬화 제외 (static도 해당)
private String name;
private int size;
public FileDto(String name, int size) {
this.name = name;
this.size = size;
}
@Override
public String toString() {
return "FileDto{name='" + name + "', size=" + size + "}";
}
}
public static void main(String[] args) {
try {
// 역직렬화 수행
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.dat"));
// readObject()는 obj.dat에 저장된 바이트 스트림을 읽어
// 클래스 메타데이터와 serialVersionUID를 확인한 후 객체 복원
// - 복원 과정에서 기본 생성자 호출 X
// - serialVersionUID가 일치하지 않으면 InvalidClassException 발생
FileDto dto = (FileDto) ois.readObject();
ois.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}