Search

Item 49. 매개변수가 유효한지 검사하라

생성일
2023/08/02 12:13
챕터
8장 - 메서드

요약

오류는 가급적 발생한 지점에서 찾을 수 있게 매개변수로 받은 값들에 대해 로직 수행 전 미리 검사하자.

메서드 몸체가 실행되기 전에 매개변수를 검사하자

인덱스는 음수가 되면 안된다거나 객체 참조는 null이 아니어야 한다는 것과 같은 제약들은 반드시 문서화 되어야하며 메서드 몸체가 시작되기 전에 검사해야한다.
이는 오류는 가능한 빨리 발생한 지점에서 잡아야한다는 일반 원칙 중 한 사례이기도 하며, 오류가 발생한 즉시 못 잡으면 오류를 감지하기도 어렵고 감지해도 발생지점을 찾기 어려워진다.
매개변수 검사를 메서드 몸체 시작 전에 하지 않는다면, 메서드 수행 중 간에 모호한 예외를 던지며 실패할 수 있거나 메서드가 수행되었지만 잘못된 결과를 반환해 미래의 알 수 없는 시점에 오류가 발생하도록 만들 수 있다.
생성자를 호출할 때에도 매개변수의 유효성을 검사하자. 생성자 매개변수의 유효성 검사는 클래스 불변식을 어기는 객체가 만들어지지 않게 하는데 꼭 필요하다.

공개 API의 매개변수 검사가 잘못되는 경우는 문서화하자

public과 protected 메서드는 매개변수가 잘못되는 경우에 던지는 예외들에 대해 문서화 해야한다.
매개변수의 제약을 문서화한다면 당연히 매개변수의 제약을 위반했을 때의 예외도 문서화 되어야한다.
/* * @param m 계수 * ... * @throws ArithmeticException m이 0보다 작거나 같으면 발생한다. */ public BingInteger mod(BigInteger m) { if (m.signum() <= 0) throw new ArithmeticException("계수(m)는 양수이어야 합니다. " + m); ... }
Java
복사
위 코드는 m 값에 null이 들어가면 NullPointerException이 발생하지만, 문서화 내용에는 해당 사항이 들어있지 않다.
문서화 내용에 해당 사항을 추가하고, 자바 7에 추가된 java.util.objects.requireNonNull 메서드를 사용하여 null에 대한 예외를 던져야 한다.
/* * @param m 계수 * ... * @throws NullPointerException m이 null인 경우 발생한다. * @throws ArithmeticException m이 0보다 작거나 같으면 발생한다. */ public BingInteger mod(BigInteger m) { BigInteger tmp = Objects.requrieNonNull(m, "계수(m)는 null이 아니어야 합니다."); if (tmp.signum() <= 0) throw new ArithmeticException("계수(m)는 양수이어야 합니다. " + m); ... }
Java
복사

단언문(assert)로 유효성 검사하기

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; ... }
Java
복사
만약 public이 아닌 메서드라면 이와 같이 단언문(assert)를 사용해 매개변수 유효성을 검증할 수 있다.
단언문은 선언된 조건이 무조건 참이라고 선언하는 것으로, 해당 조건을 만족하지 못하면 AssertionError를 던진다.
또한 단언문은 런타임에는 아무런 효과도 없고 성능 저하도 없다.

매개변수 유효성 검사의 예외

유효성 검사 비용이 지나치게 높거나 실용적이지 않을 때, 혹은 계산 과정에서 암묵적으로 검사가 수행될 때에는 매개 변수 유효성 검사를 하지 않는다.
Collections.sort(List)의 경우에는 리스트 안의 객체가 서로 상호 비교될 수 있어야 하는데, 상호 비교될 수 없는 타입의 객체가 들어 있다면 ClassCastException이 발생할 것이기 때문에 따로 검사하지 않아도 된다.
하지만 이러한 암묵적 유효성 검사에 너무 의존하다가는 실패 원자성을 해칠 수 있으니 주의하자.