Item 49 : 매개변수가 유효한지 검사하라
2021. 8. 17. 09:00
메소드와 생성자 대부분은 입력 매개변수의 값이 특정 조건을 만족하길 바란다
예를 들어
- 인덱스 값은 음수이면 안된다.
- 객체 참조는 null이 아니어야 한다
하는 식이다.
이런 제약은 반드시 문서화해야 한다.
메소드 몸체가 실행되기 전에 매개변수를 확인한다면 잘못도니 값이 넘어왔을 때
즉각적이고 깔끔한 방식으로 예외를 던질 수 있다. (유효성 검사를 한다는 의미인것 같다.)
매개변수 검사를 제대로 하지 못하면 몇가지 문제가 생긴다
- 메소드가 수행되는 중간에 모호한 예외를 던지며 실패할 수 있다.
- 더 나쁜 상황은 메소드가 잘 수행되지만 잘못된 결과를 반환할 때다.
- 매개변수 검사에 실패하면 실패 원자성을 어기는 결과를 낳을 수 있다.
- 실패 원자성 : 호출에 실패하더라도 객체는 호출 전 결과를 유지해야 함
public과 protected 메소드는 매개변수 값이 잘못됐을 때 던지는 예외를 문서화 해야한다.
@throws 자바독 태그를 사용함녀 된다.
보통은 IlleagalArgumentException, IndexOutOfBoundsException, NullPointerException 중 하나다.
매개변수 제약을 어겼을 때의 예시도 서술해줘야하는데 다음은 예시다
/**
* Returns a BigInteger whose value is {@code (this mod m}). This method
* differs from {@code remainder} in that it always returns a
* <i>non-negative</i> BigInteger.
*
* @param m the modulus.
* @return {@code this mod m}
* @throws ArithmeticException {@code m} ≤ 0
* @see #remainder
*/
public BigInteger mod(BigInteger m) {
if (m.signum <= 0)
throw new ArithmeticException("BigInteger: modulus not positive");
BigInteger result = this.remainder(m);
return (result.signum >= 0 ? result : result.add(m));
}}
- 이 메소드는 m이 null이면 m.signum 호출 때 NullPointerException을 던진다.
- 그러나 위 예시에선 확인할 수 없는데 이 설명을 BigInteger 클래스 수준에서 기술했기 때문이다.
- 클래스 수준 주석은 그 클래스의 모든 public 메소드에 적용되므로 각 메소드에 일일이 기술하는 것보다 훨씬 깔끔한 방법이다.
공개되지 않은 메소드의 경우
공개되지 않은 메소드라면 패키지 제작자가 메소드가 호출되는 상황을 통제할 수 있다.
따라서 유효한 값만이 메소드에 넘겨지리라는 것을 우리가 보증할 수 있고 그렇게 해야한다.
//재귀 정렬용 private 도우미 함수
private static void sort(long a[], int offset, int length) {
assert a != null;
assert offset >= 0 && offset <= a.length;
assert length >= 0 && length <= a.length - offset;
... // 계산 수행
}
- 여기서 핵심은 이 단언문들은 자신이 단언한 조건이 무조건 참이라고 선언한다는 것
- 단언문과 일반적인 유효성 검사가 다른점
- 실패하면 AssertionError를 던짐
- 런타임에 아무런 효과도 아무런 성능저하도 없음
정리
- 메소드나 생성자를 작성할 때 매개변수의 제약에 대해 생각해야함
- 제약들을 문서화하고 메소드 코드 시작부분에 명시적으로 검사해야 함
'책 > 이펙티브자바' 카테고리의 다른 글
Item 51 : 메소드 시그니처를 신중히 설계하라 (0) | 2021.08.19 |
---|---|
Item 50 : 적시에 방어적 복사본을 만들라 (0) | 2021.08.18 |
Item 48 : 스트림 병렬화는 주의해서 적용하라 (0) | 2021.08.16 |
Item 47 : 반환 타입으로는 스트림보다 컬렉션이 낫다 (0) | 2021.08.16 |
Item 46 : 스트림에서는 부작용 없는 함수를 사용하라 (0) | 2021.08.14 |