Growth-Collectors / effective-java

repository for effective java study
3 stars 2 forks source link

아이템 50. 적시에 방어적 복사본을 만들라 #50

Open HanaHww2 opened 1 year ago

yeGenieee commented 1 year ago

아이템 50. 적시에 방어적 복사본을 만들어라

불변식을 지키지 못한 클래스

class Period { private final Date start; private final Date end;

public Period(Date start, Date end) {
    if(start.compareTo(end) > 0) {
        try {
            throw new IllegalAccessException(this.start + "after" + this.end);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
    this.start = start;
    this.end = end;
}
public Date start() { return start; }
public Date end() { return end; }
// ... 생략

}

class Item50 { public void test() { Date start = new Date(); Date end = new Date(); Period period = new Period(start, end);

    // period의 내부를 수정
    end.setYear(3);
}

public static void main(String[] args) {
    Item50 main = new Item50();
    main.test();
}

}

- Period 클래스는 불변처럼 보이는데, 하지만 자바에서 제공하는 `Date` 클래스는 가변이어서 쉽게 불변식을 깨뜨릴 수 있다
```java
// Period 인스턴스의 내부를 공격하는 첫 번째 방법
Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
end.setYear(78); // p의 내부를 수정한다

해결 방안

생성자 매개변수의 방어적 복사본을 만든다

Period getter를 이용하여 공격

// Period 인스턴스의 내부를 공격하는 두 번째 방법
Date start = new Date();
Date end = new Date();
Period p = new Period(start, end);
p.end().setYear(78); // getter 메서드를 이용해 값을 변경한다.

가변 필드의 방어적 복사본을 반환한다

public Date start() {
    return new Date(start.getTime());
}

public Date end() {
    return new Date(end.getTime());
}
jioome commented 1 year ago

불변식을 지키기 위해 방어적 복사본을 만들어야 한다는 사실을 알았습니다! 깔끔한 정리 감사합니다

YunDaHyee commented 1 year ago

함수 작성에 있어서 매개변수의 캡슐화를 잘 적용해야겠습니다!