[Effective Java] 8 - item49 매개변수가 유효한지 검사하라.
메서드 혹은 생성자에서, 매개변수 제약은 반드시 문서화해야 하며 메서드 내 로직이 수행되기 전에 선행되어 검사해야 한다.
이와 같은 매개변수 검사를 제대로 하지 못한다면…
- 메서드 수행 중 예외를 던지며 실패
- 메서드가 수행되지만 잘못된 결과를 반환
- 메서드가 문제없이 수행되지만, 어떤 객체의 상태를 변이시켜 알 수 없는 미래에 메서드와 관련 없는 오류가 발생
위와 같은 문제가 발생할 수 있다.
public
& protected
메서드
/** * (현재 값 mod m) 값을 반환한다. 이 메서드는
* 항상 음이 아닌 BigInteger를 반환하다는 점에서 remainder 메서드와 다르다.
*
* @param m 계수(양수여야 한다.)
* @return 현재 값 mod m
* @throws ArithmeticException m이 0보다 작거나 같으면 발생한다.
* */
public BigInteger mod(BigInteger m) {
if (m.signum() <= 0)
throw new ArithmeticException("계수(m)는 양수여야 합니다. " + m);
... // 계산 수행
}
위와 같이, 매개변수의 제약을 문서화한다면 그 제약을 어겼을때 발생하는 예외도 함께 기술해야 한다.
this.strategy = Objects.requireNonNull(strategy, "전략");
Java 7부터는 java.util.Objects.requireNonNull
메서드를 사용해 더 이상 null
검사를 수동으로 하지 않아도 된다.
또한, Java 9에서는 Objects
에 checkFromIndexSize
, checkFromToIndex
, checkIndex
라는 범위 검사 기능도 더해졌다.
다만 이 메서드들은 예외 메시지를 지정할 수 없고, 리스트와 배열 전용이며 닫힌 범위는 다룰 수 없다는 단점이 있다.
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;
...// 계산 수행
}
private
메서드는 제작자가 직접 메서드 호출 상황을 통제할 수 있으므로 유효한 값만이 메서드에 넘져진다고 보증해야 한다.
이와 같은 경우, 단언문 (assert
)를 사용해 매개변수 유효성을 검사하자.
- 실패시
AssertionError
를 던진다. - 런타임에 효과 및 성능 저하가 없다.
생성자 매개변수와 같이 메서드가 직접 사용하지 않으나 나중에 쓰기 위해 저장하는 경우, 특히 더 신경 써서 검사해야 한다.
예외
다음과 같은 경우 매개변수 유효성 검사를 시행하지 않을 수도 있다.
- 유효성 검사 비용이 지나치게 높을때
- 계산 과정에서 암묵적으로 검사가 수행될 때 (
Collections.sort(List)
)
Leave a comment