매개변수 유효성 검사
// NullPointerException 발생
List<Integer> nums = Collections.synchronizedList(null);
...
메소드나 생성자의 내부 동작은 정상적인 파라미터가 전달될 것이라는 것을 전제로 한다. 예를 인덱스 값은 음수가 아니고 객체는 null이 아니라는 것이다. 하지만 개발중 실수로 잘못된 값이 전달되지 않을거라는 보장은 없기 때문에 매개변수의 유효성 검사는 필요하다. 그리고 오류를 가능한 빨리 (근본적인 오류가 발생한 곳에서) 잡는것에도 도움이 된다. 위의 코드를 보면 Collections.synchronizedList(null); 메소드를 호출한 시점부터 파라미터 유효성 검사에 걸려서 에러가 발생한다. 하지만 만약 저 에러가 발생하지 않았다면, 멀리 떨어진 곳에서 다른 형태의 에러가 발생했을 것이다.
예외 문서화
/**
* 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));
}
외부에서 사용가능한 메소드는 매개변수 값이 잘못되었을 때 던지는 예외를 문서화해야한다. 문서화된 예외를 본 개발자는 해당 메소드를 사용함에 있어서 더욱 주의를 기울일 것이다.
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;
...
}
내부에서만 사용하는 메소드라면 해당 메소드가 호출되는 상황을 통제할 수 있다. 오직 바람직한 파라미터만을 해당 메소드에 전달하면 되고 그래야 한다. 이때는 assert를 사용하여 유효성을 검사할 수 있다. assert문은 true/false로 판단 가능한 조건을 명시적으로 선언하고, java 실행시 특정 플래그를 통해 런타임에도 유효성 검사를 수행한다. 하지만 플래그가 없는 일반적인 실행환경에서는 아무런 동작도 하지 않는다.
728x90
'STUDY > 이펙티브자바' 카테고리의 다른 글
8-3) 메소드 시그니처를 신중히 설계하라 (0) | 2022.12.01 |
---|---|
8-2) 방어적 복사본을 만들라 (0) | 2022.11.29 |
6-3) 비트 필드 대신 EnumSet을 사용하라 (0) | 2022.11.03 |
6-2) ordinal 메소드 대신 인스턴스 필드를 사용하라 (0) | 2022.11.03 |
6-1) int 상수 대신 enum을 사용하라 (0) | 2022.11.02 |