직렬화 (Serializaion)
직렬화는 객체를 저장 가능한 상태 혹은 전송 가능한 상태(네트워크 상의 데이터 스트림 형태)로 변환하는 것
- 객체를 저장, 전송할 수 있는 특정 포맷 상태로 바꾸는 과정
역직렬화 (Deserialization)
- 특정 포맷 상태의 데이터를 다시 객체로 변환하는 것
데이터 직렬화 포맷
- CSV, XML, JSON 형태의 직렬화
- 사람이 읽을 수 있음
- 저장 공간의 효율성이 상대적으로 떨어지고, 파싱 하는 시간이 오래 걸림
- 주로 데이터의 양이 적을 때 사용
- Binary 직렬화
- 사람이 읽을 수 없음
- 저장 공간의 효율성이 상대적으로 높고, 파싱 하는 시간이 빠름
- 주로 데이터의 양이 많을 때 사용
- 모든 시스템에서 사용 가능
- java 직렬화
- java 시스템 간의 데이터 교환이 필요할 때 사용
- Serializable 인터페이스를 구현함으로써 사용 가능
Java에서 직렬화가 필요한 이유
- 일반적으로 Java에서의 직렬화는 객체를 Binary 형태로 변환하는 것을 뜻함
- disk에 객체를 저장하거나 컴퓨터 네트워크 상으로 객체를 전송하고 싶다면 Binary 형태로 바꿔야 지만 가능
- 객체 그 자체는 disk나 네트워크 장비가 이해할 수 없을 것
직렬화
직렬화 조건
- serialVersionUID가 없는 것이 이상하다고 생각할 수 있는데, 아래에서 자세히 알아볼 것
- java.io.Serializable 인터페이스를 구현함으로써 Java 직렬화를 수행할 수 있음
- transient 키워드를 사용하면 해당 변수는 직렬화에서 제외 가능
public class Member implements Serializable {
private String name;
private String email;
private int age;
public Member(String name, String email, int age) {
this.name = name;
this.email = email;
this.age = age;
}
@Override
public String toString() {
return String.format("Member{name='%s', email='%s', age='%s'}", name, email, age);
}
}
직렬화 방법
- java.io.ObjectOutputStream 를 사용하여 직렬화를 진행
public static void main(String[] args){
Member member = new Member("김배민", "deliverykim@baemin.com", 25);
byte[] serializedMember;
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
try (ObjectOutputStream oos = new ObjectOutputStream(baos)) {
oos.writeObject(member);
// serializedMember -> 직렬화된 member 객체
serializedMember = baos.toByteArray();
}
}
// 바이트 배열로 생성된 직렬화 데이터를 base64로 변환
System.out.println(Base64.getEncoder().encodeToString(serializedMember));
}
역직렬화
역직렬화 조건
- 직렬화 대상이 된 객체의 클래스가 class path에 존재해야 하며 import되어 있어야 함
- class path란?
- JVM이 프로그램을 실행할 때, class 파일을 찾는 데 기준이 되는 파일 경로
- class path란?
- 자바 직렬화 대상 객체는 동일한 serialVersionID를 가지고 있어야 함
역직렬화 방법
- java.io.ObjectInputStream 을 사용하여 역직렬화를 진행
public static void main(String[] args){
// 직렬화 예제에서 생성된 base64 데이터
String base64Member = "...생략";
byte[] serializedMember = Base64.getDecoder().decode(base64Member);
try (ByteArrayInputStream bais = new ByteArrayInputStream(serializedMember)) {
try (ObjectInputStream ois = new ObjectInputStream(bais)) {
// 역직렬화된 Member 객체를 읽어온다.
Object objectMember = ois.readObject();
Member member = (Member) objectMember;
System.out.println(member);
}
}
}
출처 : https://code-lab1.tistory.com/289, https://steady-coding.tistory.com/576
'Programming Language > JAVA' 카테고리의 다른 글
[JAVA] 날짜 (LocalDate, LocalDateTime, Date, Calendar) (0) | 2024.11.26 |
---|---|
[JAVA] Integer (0) | 2024.10.17 |
[JAVA] StringBuffer & StringBuilder 특징 (0) | 2023.10.20 |
[JAVA] 정적 & 동적 (1) | 2023.10.20 |
[JAVA] 디자인패턴 (1) | 2023.10.20 |