직렬화(Serialization)
자바의 직렬화는 객체를 바이트 형태로 변환하는 기술을 말한다. 이를 통해 자바 시스템 내부에서 사용되는 객체 또는 데이터를 외부의 자바 시스템에서도 사용할 수 있도록 바이트(byte) 형태로 변환하여 전송하거나 저장할 수 있다.
직렬화/역직렬화 과정
// Employee라는 클래스를 정의
// Serializable 인터페이스를 구현함으로써 이 클래스의 객체는 직렬화 가능함을 나타냄
import java.io.Serializable;
public class Employee implements Serializable {
private String name;
private int id;
// getters, setters 생략
}
위 객체를 직렬화하는 코드
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
public class SerializeExample {
public static void main(String[] args) {
Employee e = new Employee(); // 직렬화할 Employee 객체를 생성
e.setName("John");
e.setId(101);
try {
// 객체를 저장할 파일을 위한 FileOutputStream을 생성
FileOutputStream fileOut = new FileOutputStream("/tmp/employee.ser");
// ObjectOutputStream을 생성하여 Employee 객체를 직렬화하고 파일에 쓰기
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(e);
// 스트림 닫기
out.close();
fileOut.close();
System.out.println("Serialized data is saved in /tmp/employee.ser");
} catch (IOException i) {
i.printStackTrace();
}
}
}
이렇게 직렬화된 객체를 다시 역직렬화하는 코드
import java.io.FileInputStream;
import java.io.ObjectInputStream;
public class DeserializeExample {
public static void main(String[] args) {
Employee e = null; // 역직렬화한 객체를 저장할 변수를 선언
try {
// 직렬화된 객체가 저장된 파일을 위한 FileInputStream을 생성
FileInputStream fileIn = new FileInputStream("/tmp/employee.ser");
// ObjectInputStream을 생성하여 파일로부터 객체를 읽어와서 역직렬화
ObjectInputStream in = new ObjectInputStream(fileIn);
e = (Employee) in.readObject();
// 스트림을 닫기
in.close();
fileIn.close();
} catch (IOException i) {
i.printStackTrace();
} catch (ClassNotFoundException c) {
System.out.println("Employee class not found");
c.printStackTrace();
}
// 역직렬화된 객체의 정보를 출력
System.out.println("Deserialized Employee...");
System.out.println("Name: " + e.getName());
System.out.println("ID: " + e.getId());
}
}
직렬화 시 주의사항
- 'serrialVersionUID'는 직렬화된 객체와 해당 객체의 클래스 정의가 일치하는지 검증하기 위해 사용되는 ID이다. 클래스의 정의가 변경되면 이 ID가 달라져 역직렬화가 실패할 수 있다. 따라서 클래스를 변경할 때 이 ID를 명시적으로 관리하는 것이 좋다.
- 직렬화된 객체는 클래스의 private 필드까지 모두 포함하므로, 부적절하게 역직렬화된 경우 보안 문제가 발생할 수 있다.
- Serializable 인터페이스를 구현하지 않은 클래스의 객체를 직렬화 하려고 하면 'java.io.NotSerializableException'이 발생한다. 또한, 직렬화 가능한 클래스의 필드 중에서 특정 필드를 직렬화에서 제외하려면 그 필드를 'transient'로 선언해야 한다.
- 개발자가 직접 컨트롤할 수 없는 클래스, 자주 변경되는 클래스는 직렬화 사용을 지양한다.
- 역직렬화에 실패하는 상황에 대한 예외처리는 필수로 구현한다.
- 직렬화 데이터는 타입, 클래스 메타정보를 포함하므로 사이즈가 크다. 트래픽에 따라 비용 증가 문제가 발생할 수 있기 때문에 JSON 포맷으로 변경하는 것이 좋다.
[참고] https://gyoogle.dev/blog/computer-language/Java/Serialization.html
'Languages > Java' 카테고리의 다른 글
[Java] Casting (0) | 2023.08.10 |
---|---|
[Java] 문자열 클래스 & 오브젝트 클래스 (0) | 2023.08.10 |
[Java] 오토 박싱(Autoboxing) & 오토 언박싱(Unboxing) (0) | 2023.07.31 |
[Java] Primitive Type & Reference Type (0) | 2023.07.31 |
[Java] Call by Value & Call by Reference (0) | 2023.07.24 |