"클래스의 클라이언트가 불변성을 파괴하기 위해 최선을 다할 것이라는 가정 하에 방어적으로 프로그래밍해야 합니다."
안전한 언어로서의 Java:
- Java는 C/C++에서 흔히 발생하는 메모리 오류를 방지하지만 다른 클래스와의 원치 않는 상호 작용으로부터 클래스를 완전히 격리하지는 않습니다.
- 클래스의 클라이언트가 불변성을 위반하려고 시도할 수 있다는 가정하에 방어적인 프로그래밍이 필요합니다.
불변 클래스 및 보안:
- 불변으로 보이지만 Date와 같은 객체의 가변성으로 인해 손상될 수 있는 클래스 "Period"의 예
- 해결책: 생성자에서 변경 가능한 매개변수를 수신할 때 방어적인 복사본을 만드세요.
public Period(Date start, Date end) {
this.start = new Date(start.getTime()); // Cópia defensiva
this.end = new Date(end.getTime());
if (this.start.compareTo(this.end) > 0)
throw new IllegalArgumentException(start + " after " + end);
}
빌더의 방어 복사본:
- 취약점(예: TOCTOU 공격)을 방지하려면 매개변수를 검증하기 전에 방어 복사본을 만들어야 합니다.
- 잠재적으로 신뢰할 수 없는 개체의 방어 복사본에는 clone()을 사용하지 말고 정적 생성자나 팩토리 메서드를 선호하세요.
Getter 및 가변성:
- 문제: Getter는 변경 가능한 내부 구성 요소를 노출하여 외부 변경을 허용할 수 있습니다.
- 해결책: Getter는 변경 가능한 개체의 방어 복사본을 반환해야 합니다.
public Date getStart() {
return new Date(start.getTime()); // Cópia defensiva
}
변경 가능한 클래스에 적용:
- 방어 복사는 클라이언트 제공 변경 가능 개체에 대한 참조를 저장하는 변경 가능 클래스에도 적용됩니다.
- 예: 세트나 맵에 객체를 저장할 때 나중에 객체를 수정할 수 있는지 여부를 고려해야 합니다.
내부 구성품 반품:
- 변경 가능한 내부를 반환할 때는 방어적 복사본이나 변경 불가능한 뷰 반환을 고려하세요.
불변 객체 사용:
- 가능한 한 불변 객체를 내부 구성 요소로 사용하여 방어 복사본이 필요하지 않도록 하세요.
비용 및 대안:
- 방어적 사본은 성능에 영향을 미칠 수 있습니다. 대안으로는 문서나 명확한 사용 계약에 의존하는 것이 있습니다.
- 디자인 패턴(예: 래퍼)과 같이 명시적인 제어권 이전의 경우 방어적인 복사가 생략될 수 있습니다.
결론:
- 비용이 비현실적이거나 상호 신뢰가 확립되고 명확한 문서가 필요한 경우를 제외하고 클래스의 무결성을 보호하기 위해 방어용 사본을 사용하세요.
책의 예:
위 내용은 항목 필요한 경우 방어용 복사본을 만듭니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!