직렬화(Serialization)와 외부화(Externalization)는 모두 자바 객체를 바이트 스트림(byte stream)으로 변환하고, 이를 데이터베이스나 메모리에 저장하는 기술입니다. java.io.Serializable 인터페이스를 구현한 클래스는 직렬화가 가능하며, 반면 외부화는 애플리케이션의 요구 사항에 맞춰 직렬화 과정을 직접 제어하고 싶을 때 사용하는 방식입니다. 참고로 Externalizable 인터페이스는 java.io.Serializable을 확장한 인터페이스입니다.
직렬화 vs 외부화 핵심 비교표
| 번호 | 구분 기준 | 직렬화 (Serialization) | 외부화 (Externalization) |
|---|---|---|---|
| 1 | 인터페이스 | 마커(marker) 인터페이스로, 별도의 메서드 선언이 없습니다. | readExternal()과 writeExternal() 두 개의 메서드를 포함합니다. |
| 2 | 구현 로직 | 인터페이스를 구현한 클래스는 직렬화 책임을 JVM에 위임합니다. JVM은 내부적으로 readObject()와 writeObject()를 사용해 객체를 처리합니다. | 개발자가 readExternal()과 writeExternal() 메서드를 오버라이딩하여 직렬화 로직을 직접 제어할 수 있습니다. |
| 3 | 변수 제외 방법 | JVM이 직렬화 및 역직렬화 과정에서 transient로 선언된 변수를 자동으로 무시합니다. | 개발자가 특정 변수를 제외하는 자체 로직을 직접 작성할 수 있습니다. |
| 4 | 성능 | 내부적으로 리플렉션(reflection)을 사용하기 때문에 상대적으로 성능이 느립니다. | 구현 방식에 대한 완전한 제어권을 가지므로, 최적화된 방식으로 성능을 개선할 수 있습니다. |
| 5 | 상속 관계에서의 직렬화 | 1. 슈퍼클래스가 직렬화 불가능해도 서브클래스는 직렬화할 수 있습니다. 2. 서브클래스가 직렬화되지 않아도 슈퍼클래스가 직렬화 가능하면 자동으로 처리됩니다. | 동일한 원칙을 Externalizable에도 적용할 수 있습니다. |
Externalizable 예제 코드
class ExternalizableExample implements Externalizable {
Integer id;
@Override
public void writeExternal(ObjectOutput out) throws IOException {
out.writeInt( id );
}
@Override
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
this.id = in.readInt();
}
}Serializable 예제 코드
class SerializableExample implements Serializable {
private static final long serialVersionUID = 5081877L;
String name;
}정리하면, 간단하게 객체를 저장하고 복원해야 한다면 Serializable이 편리하지만, 직렬화 대상 필드 선택이나 성능 최적화처럼 세밀한 제어가 필요하다면 Externalizable을 사용하는 것이 좋습니다.