방어적 복사의 필요성

  1. 객체의 불변성 유지: 객체가 다른 클래스나 메서드에 의해 변경되는 것을 방지하기 위해, 내부적으로 사용되는 객체를 복사하여 제공함으로써 원본 객체가 영향을 받지 않도록 합니다.
  2. 스레드 안전성: 멀티스레드 환경에서 한 스레드가 객체를 수정할 수 없는 구조를 만들기 위해 방어적 복사를 사용하여 다른 스레드가 작업하는 동안 원본 객체가 변하지 않도록 할 수 있습니다.
  3. 보안: 객체의 내부 상태를 노출하지 않기 위해 방어적 복사를 통해 외부에 전달되는 객체가 원본 객체의 상태를 변경할 수 없도록 합니다.

방어적 복사의 예시

java
코드 복사
import java.util.Date;

public class User {
    private final String name;
    private final Date birthDate; // 가변 객체

    public User(String name, Date birthDate) {
        this.name = name;
        this.birthDate = new Date(birthDate.getTime()); // 방어적 복사
    }

    public Date getBirthDate() {
        return new Date(birthDate.getTime()); // 방어적 복사
    }
}

위의 User 클래스에서 birthDateDate 객체로, 가변 객체입니다. 생성자와 getter에서 방어적 복사를 사용하여 Date 객체의 원본 상태가 외부에서 변경되지 않도록 합니다.

방어적 복사의 장점과 단점

방어적 복사는 특히 API 설계나 불변 객체를 사용할 때 중요한 개념이며, 객체 지향 프로그래밍에서 객체의 상태 관리와 관련된 문제를 방지하는 데 유용합니다.

getter를 지양해야 하는 이유를 찿아봐야 할 것같은데 그 내용이야

네, 맞습니다! 객체 지향 프로그래밍에서 참조 타입의 특성을 이해하는 것이 중요합니다. birthDate가 가변 객체(예: Date)로 선언되어 있기 때문에, 이 객체를 반환할 때 반환된 참조를 통해 외부에서 객체의 상태를 변경할 수 있습니다.

참조 타입의 특성

  1. 객체의 참조: 객체를 생성할 때 메모리에 위치한 그 객체에 대한 참조가 생성됩니다. 이 참조는 객체의 주소를 가지고 있으며, 이를 통해 객체의 속성에 접근할 수 있습니다.
  2. 가변 객체: Date와 같은 가변 객체는 상태가 변경될 수 있는 객체입니다. 따라서 그 객체에 대한 참조를 외부에 제공하면, 외부 코드에서 객체의 상태를 변경할 수 있습니다.