본문 바로가기
Effective Java

[Effective Java] 아이템49 매개변수가 유효한지 검사하라

by byeongoo 2021. 7. 4.

■ 매개 변수가 유효한지 검사하라

메서드와 생성자 대부분은 입력 매개변수의 값이 특정 조건을 만족하기를 바란다. 이런 제약은 반드시 문서화해야 하며 메서드 몸체가 시작되기전에 검사해야 한다. 안그러면 실행되다가 예외가 발생할 수 있고, 더 나쁜 경우는 잘못된 값을 반환할 수 있다.

 

public, protected 메서드는 매개변수 값이 잘못됐을 때 던지는 예외를 문서화 해야한다. 

/**
 * 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} &le; 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인지 검사하는 코드가 없는데 그 이유는 이 설명을 BigInteger 클래스 수준에서 기술했기 때문이다. 

 

자바 7에 추가된 java.uti.Objects.requireNonNull 메서드는 유연하고 사용하기 편하니, 더 이상 null 검사를 수동으로 하지 않아도 된다.

import java.util.Objects;

public class NullCheckTest {

    public static void main(String[] args) {
        String s = null;
        Objects.requireNonNull(s, "s가 null 입니다.");
    }

}

 

실행 결과

 

■ 단언문(Assert)

public이 아닌 메서드라면 단언문(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;
    //계산 수행 ...
}

 

일반적인 유효성 검사와 단언문이 다른 점

  1. 실패하면 AssertionError를 던진다.
  2. 런타임에 아무런 효과도, 아무런 성능 저하도 없다. (단, java를 실행할 때 명령줄에서 -ea 혹은 --enableassertions 플래그를 설정하면 런타임에 영향을 준다.)

 

■ 예외 상황

메서드 몸체 실행 전에 매개변수 유효성을 검사해야 한다는 규칙에도 예외는 있다. 유효성 검사 비용이 지나치게 높거나 실용적이지 않을 때, 혹은 계산 과정에서 암묵적으로 검사가 수행될 때 이다.

 

예를 들어 Collections.sort(List)처럼 객체 리스트를 정렬하는 메서드를 생각해보면 리스트 안의 객체들은 모두 상호 비교될 수 있어야 하며, 정렬 과정에서 이 비교가 이뤄집니다. 만약 상호 비교될 수 없는 타입의 객체가 들어있다면 그 객체와 비교할 때 ClassCastException을 던진다. 따라서 비교하기 앞서 리스트 안의 모든 객체가 상호 비교될 수 있는지 검사해봐야 별다른 이익이 없다.

 

■ 핵심 정리

  • 메서드나 생성자 생성 시 매개변수들 제약 코드 시작 부분에 검사 및 문서화