직렬화란 사실 자바에서만 사용되는 개념은 아니다.
용어의 설명은 CS에서 객체의 상태를 저장하거나 전송 가능한 형태로 변환하는 프로세스를 의미하는데 대부분의 다른 프로그래밍 언어들과 마찬가지로 자바에서도 중요한 개념 중 하나이다.또한 자바에서는 java.io.Serializable를 활용한 ByteStream 직렬화만이 직렬화(Serialization) 라고 하며 Marshalling은 JSON, CSV 등 다른 포멧으로 직렬화하는 것 까지 포함하는 더 포괄적인 개념.
(API 서버를 구축할 때 DTO클래스 구현이 생각날 수도 있는데 직렬화와는 다른 개념이다.)
ObjectOutputStream
을 이용하여 직렬화 할 수 있다.
직렬화 하려는 객체는 java.io.Serializable
인터페이스를 상속해야한다.
ex)
// 직렬화 가능한 클래스
class Person implements Serializable {
String name;
int age;
transient String gender; // transient는 직렬화 대상에서 제외
public Person(String name, int age) {
this.name = name;
this.age = age;
}
...
}
...
Person person = new Person("A", 10);
// 직렬화
// 파일 출력 스트림 생성
FileOutputStream fileOutput = new FileOutputStream("person.ser");
// 객체 출력 스트림 생성
ObjectOutputStream objectOutput = new ObjectOutputStream(fileOutput);
// 객체를 직렬화하여 파일에 쓰기
objectOutput.writeObject(person);
// 객체,파일 출력 스트림 닫기
objectOutput.close();
fileOutput.close();
// 역직렬화
// 파일 입력 스트림 생성
FileInputStream fileInput = new FileInputStream("person.ser");
// 객체 입력 스트림 생성
ObjectInputStream objectInput = new ObjectInputStream(fileInput);
// 파일로부터 직렬화된 객체 읽어오기
deserializedPerson = (Person) objectInput.readObject();
// 객체, 파일입력 스트림 닫기
objectInput.close();
fileInput.close();
// 출력 : A 10
System.out.println(deserializedPerson.name + " " + deserializedPerson.age);
Serializable
인터페이스를 상속한다면 serialVersionUID 값을 컴파일러가 클래스의 기본 해쉬값으로 할당한다.
이 값은 클래스의 직렬화 버전을 명시하는 데 사용되며 이 값이 다르다면InvalidClassException
예외를 발생시킨다.
그래서 주로 서버 분산환경에서 데이터의 일관성을 유지하는데 도움을 주지만 변경 내용이 미미하더라도 엄격하게 예외를 발생시키기 때문에 번거로울 수 있다.
(경우에 따라 @SuppressWarnings("serial") 로 무시가 가능하지만 버전관리의 이점을 잃게 된다.)
이 경우 직접 serialVersionUID 값을 할당할 수 있는데 변경내용이 미미한 경우 변경 전과 같은 값을 할당함으로써 예외를 방지할 수 있다.
(멤버 변수 제거 및 이름 변경은 오류는 발생하지 않지만 데이터는 기본적으로 누락됨) 참고
serialVersionUID를 직접 관리하려면 private static final long 으로 선언해야 한다.
역직렬화 시 문제를 방지하기 위해 final이여야 하며 일관성 있게 관리해야 한다.
대부분의 단점은 보완할 수 있는 방법이 딱히 없기 때문에 우아한형제들 기술블로그 에서는
1. 외부로 저장되는 데이터는 짧은 만료시간의 데이터를 제외하고 자바 직렬화를 사용을 지양
2. 역직렬화시 반드시 예외가 생긴다는 것을 생각하고 개발
3. 자주 변경되는 비즈니스적인 데이터를 자바 직렬화을 사용X
4. 긴 만료 시간을 가지는 데이터는 JSON 등 다른 포맷을 사용하여 저장
위와 같은 규칙을 말하고 있다.