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

이진호·2022년 9월 9일
0

Effective Java

목록 보기
8/11
post-thumbnail

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

메서드 몸체가 실행되기 전에 매개변수를 확인한다면 잘못된 값이 넘어왔을 때 즉각적이고 깔끔한 방식으로 예외를 던질 수 있다.

매개변수 검사를 제대로 하지 못하면 발생하는 문제

  1. 메서드가 수행되는 중간에 모호한 예외를 던지며 실패할 수 있다.
  2. 메서드는 문제없이 수행됐지만, 어떤 객체를 이상한 상태로 만들어놓아 미래의 알 수 없는 시점에 이 메서드와 관련없는 오류가 발생할 수 있다. 즉 실패 원자성(failure atomicity, Item 76)을 어길수 있다.

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

  • 이 경우 @throws 자바독 태그를 사용하면 된다(Item 74).
  • 보통 IllegalArgumentException, IndexOutOfBoundsException, NullPointerException 중 하나 발생(Item 72).
  • 매개변수 제약을 문서화할 시 제약을 어겼을 때 발생하는 예외도 함께 기술해야 한다.

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

  • 원하는 예외 메시지도 지정 가능.
  • 입력을 그대로 반환하므로 값을 사용하는 동시에 null 검사를 수행할 수 있음.
this.strategy = Objects.requireNonNull(strategy, "전략");
  • 자바 9에서는 Objects에 범위 검사 기능도 더해짐. checkFromIndexSize, checkFromToIndex, checkIndex 메서드들인데, null 검사 만큼 유연하지는 않다. 예외 메시지를 지정할 수 없고, 리스트와 배열 전용으로 설계되었으며, 닫힌 범위(closed range; 양 끝단 값을 포함하는 범위)는 다루지 못함.

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 옵션을 주면 영향을 줌).

메서드가 직접 사용하지는 않으나 나중에 쓰기 위해 저장하는 매개변수는 특히 더 신경 써서 검사해야 한다.

  • 나중에 예외가 발생하므로 추적하기 어려워 디버깅이 상당히 괴로워질 수 있다.
  • 생성자 매개변수의 유효성 검사는 클래스 불변식을 어기는 객체가 만들어지지 않게 하는 데 꼭 필요하다.

메서드 몸체 실행 전에 매개변수 유효성을 검사해야 하는 규칙에도 예외는 있다.

  • 유효성 검사 비용이 지나치게 높거나 실용적이지 않을 때, 혹은 계산 과정에서 암묵적으로 검사가 수행되는 경우.
  • 그러나 암묵적 유효성 검사에 너무 의존했다가는 실패 원자성(Item 76)을 해칠 수 있으니 주의.
  • 계산 중 잘못된 매개변수 값을 사용해 발생한 예외와 API 문서에서 던지기로 한 예외가 다를 수도 있음. 이런 경우에는 예외 번역(exception translate) 관용구를 사용하여 API 문서에 기재된 예외로 번역해줘야 한다(Item 73)

핵심 정리

메서드나 생성자를 작성할 때면 그 매개변수들에 어떤 제약이 있을지 생각해야 한다. 그 제약들을 문서화하고 메서드 코드 시작 부분에서 명시적으로 검사해야 한다. 이런 습관을 반드시 기르도록 하자. 그 노력은 유효성 검사가 실제 오류를 처음 걸러낼 때 충분히 보상받을 것이다.

출처

0개의 댓글