직렬화에서 writeObject(), readObject() 함수

·2025년 4월 24일

전체 코드는

class User {
    String name;
    String nickname;
}

class AirUser extends User implements Serializable {
	int age;
    
    private void writeObject(ObjectOutputStream out) throws IOException {
        out.writeUTF(name);
        out.writeUTF(password);
        out.defaultWriteObject();
    }

    private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
        name = in.readUTF();
        password = in.readUTF();
        in.defaultReadObject();
    }
}

Serializable 코드를 보면 아무 것도 없는데 writeObject(), readObject()는 어디에서 누가 호출을 해서 사용을 할까?

public interface Serializable {
}

자바에서 private void writeObject(ObjectOutputStream out) throws IOException {} 메서드는 오버라이딩(override)이 아닌데도 갑자기 호출되는 것처럼 보일 수 있습니다.
이 메서드는 자바의 직렬화(Serialization) 과정에서 특별한 역할을 합니다.

  • 이 메서드는 자바의 Serializable 인터페이스를 구현한 클래스에서 직렬화 동작을 커스터마이즈하고 싶을 때 사용하는 특수 메서드입니다.
  • 이름과 시그니처가 정확히 private void writeObject(ObjectOutputStream out) throws IOException이어야 하며, 접근 제어자가 반드시 private 이어야 자동으로 호출됩니다.

누가? 호출을 한다 말이야~

  • 오버라이딩이 아니라, JVM의 직렬화 엔진이 리플렉션(reflection)으로 이 메서드를 찾아 호출합니다. 즉, ObjectOutputStream.writeObject()를 호출할 때, 해당 객체에 이 특수한 private writeObject 메서드가 있으면 자동으로 실행됩니다.
  • 이 메서드는 상속 구조에서 오버라이딩되지 않습니다.
    각 클래스가 자신의 private writeObject를 가질 수 있습니다.
    JVM이 클래스별로 찾아 호출하기 때문에, 오버라이딩이 아니라 클래스별 직렬화 커스터마이즈 포인트입니다.

왜 private인가?

  • 외부에서 임의로 호출하지 못하게 하여, 직렬화 시스템의 무결성을 보장하기 위함입니다.
  • 만약 public이나 protected로 선언하면, 서브클래스에서 오버라이드가 가능해져 직렬화 프로토콜이 꼬일 수 있습니다.
    그래서 반드시 private으로 선언해야만 JVM이 정확하게 해당 클래스의 메서드만 호출할 수 있습니다.
profile

0개의 댓글