티스토리 뷰
직렬화(Serializable)에 대해서 가볍게 살펴보겠습니다.
Effective Java 2/E에서 객체 직렬화 API에 대해서 이렇게 정의하고 있습니다.
바이트 스트림(byre stream)으로 인코딩(encoding)하거나, 바이트 스트림 인코딩에서 객체를 복원하는 프레임워크 입니다.
객체를 바이트 스트림으로 인코딩하는 것을 직렬화(serialization)
라고 하고, 그 반대는 역직렬화(deserialization)
입니다.
기본적인 직렬화 만드는 조건
기본적인 직렬화 조건은 java.io.Serializable
인터페이스를 상속받아야 합니다.
우아한형제들의 기술 블로그에서 가져온 소스를 기반으로 예를들면 다음과 같습니다.
package woowahan.blog.exam1;
/** 직렬화 할 회원 클래스 */
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;
}
// Getter 생략
@Override
public String toString() {
return String.format("Member{name='%s', email='%s', age='%s'}", name, email, age);
}
}
직렬화 방법
기본적인 자바 직렬화는 방법은 java.io.ObjectOutputStream
을 통해 생성할 수 있습니다.
직렬화 만드는 소스도 우아한형제들의 기술 블로그에서 가져온 소스를 기반으로 객체를 byte[] 로 변경하겠습니다.
public class SampleSerialization {
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));
}
}
ObjectOutputStream 의 writeObject() 을 활용하여 역직렬화 하는 것을 확인 할 수 있습니다.
역직렬화 조건
역직렬화 조건은 크게 두가지로 나누면
-
직렬화 대상이 된 객체의 클래스가 클래스 패스에 존재해야 하며 import 되어 있어야 합니다.
- 중요한 점은 직렬화와 역직렬화를 진행하는 시스템이 서로 다를 수 있다는 것을 반드시 고려해야 합니다.
-
자바 직렬화 대상 객체는 동일한
serialVersionUID
을 가지고 있어야 합니다.private static final long serialVersionUID = <무작위로 고른 Long 값>;
직렬 버전 UID 는 별도로 선언 안하면 자동으로 생성되어 위의 직렬화 생성 소스에는 생략하였습니다.
직렬버전 UID를 지정하지 않았을 때 장점
1.직렬버전 UID 때문에 생길 수 있는 잠재적 호환성 문제가 사라집니다.
2.성능이 조금 개선되는 효과가 있습니다.
직렬버전 UID를 지정하지 않았을 때 단점
실행 시간에 UID을 만드느라 시간이 많이 걸리는 계산을 하게 됩니다.
출처 : Effective Java 2/E
역직렬화
역직렬화 만드는 소스도 우아한형제들의 기술 블로그에서 가져온 소스를 기반으로 byte[] 을 객체로 변경하겠습니다.
// 직렬화 예제에서 생성된 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);
}
}
ObjectInputStream 의 readObject() 을 활용하여 역직렬화 하는 것을 확인 할 수 있습니다.
마무리
직렬화(Serialization) 과 역직렬화에 대해서 간단히 살펴보았습니다.
간단히 정의하면 객체를 바이트 스트림으로 변화시키는 것이 직렬화이며, 직렬화된 바이트 스트림을 객체로 변화 시키는 것이 역직렬화 입니다.
서블릿 세션, 캐시, 자바 RMI(Remote Method Invocation) 등 다양한 부분에서 활용되고 있는 기술로 기억하면 좋을거 같습니다.
참고
도서 : Effective Java 2/E
'프로그래밍 > Java' 카테고리의 다른 글
Java Transient 에 대해서 알아보자. (0) | 2020.06.16 |
---|---|
DI(의존성주입) 은 무엇인가? (0) | 2018.07.14 |
[Java]enum을 이용한 for-each 문 (0) | 2017.12.18 |
[Java]직렬화(Serializable) (0) | 2017.12.18 |
- 임용고시
- 디자인패턴
- push
- 알고리즘
- MCC
- 안드로이드
- flutter
- missioon
- Android Studio
- 미션차이나센터
- 탁구
- 패턴
- 코틀린
- swift
- DI
- 스코어헬퍼
- IOS
- IT
- 고시문헬퍼
- Android
- missionchina
- Kotlin
- view
- 선교
- issue
- java
- 점수판
- 고시문
- RXjava
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |