## 목표
- 역직렬화 과정에서 불변성이 깨지는 문제를 방지하는 방법을 알아보자.
## 핵심 요약
직렬화와 역직렬화
- 직렬화
자바에서 객체를 파일에 저장하거나, 네트워크로 보내려면 숫자나 문자처럼 변환하는 과정을 직렬화라고 함.
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("data.obj"));
out.writeObject(new Person("ssddo", 25)); // 객체를 파일로 저장
out.close();
- 역직렬화
파일에서 다시 객체로 복원하는 과정을 역직렬화라고 함.
ObjectInputStream in = new ObjectInputStream(new
FileInputStream("data.obj"));
Person p = (Person) in.readObject(); // 파일에서 객체로 복원
in.close();
readObject란?
- readObject(ObjectInputStream s)는 객체를 파일에서 읽어올 때 자동으로 실행되는 메서드다.
- "숨겨진 생성자"처럼 작동해서 객체를 복원하는 역할을 한다.
- 하지만 보안 문제가 발생할 가능성이 있다.
1️⃣ readObject의 위험성
- readObject는 사실상 "바이트 스트림을 받는 또 다른 생성자" 역할을 한다.
- 따라서 기존 생성자에서 수행하는 불변성 유지 및 방어적 복사가 반드시 필요하다.
- 그렇지 않으면 악의적인 직렬화 데이터를 이용한 공격이 가능해진다.
2️⃣ readObject를 사용할 때 주의할 점
🧩 방어적 복사를 하자
private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject(); // 기본 역직렬화 수행
// 🔒 원본을 보호하기 위해 새로운 객체로 복사
start = new Date(start.getTime());
end = new Date(end.getTime());
// 🚨 유효성 검사 (잘못된 값 방지)
if (start.compareTo(end) > 0) {
throw new InvalidObjectException("시작 날짜가 종료 날짜보다 늦을 수 없습니다!");
}
}
- Date, ArrayList 같은 가변 객체는 외부에서 값을 바꿀 수 있다.
- 따라서 위의 예시처럼 readObject에서 새로운 복사본을 만들어 원본을 보호해주어야 한다.
🧩 불변식을 검사하여 유효하지 않은 객체 생성 시 예외를 던져라
InvalidObjectException을 사용해 객체 생성 자체를 막을 수 있다. (위 예시)
🧩 readObject 내부에서 절대 재정의 가능한 메서드를 호출하지 말라
readObject 실행 중 하위 클래스의 오버라이딩 메서드가 호출되면 예측할 수 없는 동작이 발생할 수 있다.
💡 핵심 정리
readObject는 새로운 생성자와 같으므로, 불변성을 유지할 수 있도록 방어적으로 작성해야 한다.
- 가변 객체는 반드시 방어적 복사(Defensive Copy) 를 수행해야 한다.
InvalidObjectException을 활용해 불변식 위반을 사전에 차단하라.
- 재정의 가능한 메서드를 호출하지 않도록 주의하라.
## 목표
## 핵심 요약
직렬화와 역직렬화
자바에서 객체를 파일에 저장하거나, 네트워크로 보내려면 숫자나 문자처럼 변환하는 과정을 직렬화라고 함.파일에서 다시 객체로 복원하는 과정을 역직렬화라고 함.readObject란?
1️⃣ readObject의 위험성
2️⃣ readObject를 사용할 때 주의할 점
🧩 방어적 복사를 하자
🧩 불변식을 검사하여 유효하지 않은 객체 생성 시 예외를 던져라
InvalidObjectException을 사용해 객체 생성 자체를 막을 수 있다. (위 예시)🧩 readObject 내부에서 절대 재정의 가능한 메서드를 호출하지 말라
readObject실행 중 하위 클래스의 오버라이딩 메서드가 호출되면 예측할 수 없는 동작이 발생할 수 있다.💡 핵심 정리
readObject는 새로운 생성자와 같으므로, 불변성을 유지할 수 있도록 방어적으로 작성해야 한다.InvalidObjectException을 활용해 불변식 위반을 사전에 차단하라.