메서드와 생성자 대부분이 입력 매개변수의 값이 특정 조건을 만족하기를 바란다. 이러한 제약은 메서드 로직이 실행되기 전, 즉, 메서드 도입 부분에서 매개변수를 확인해 잘못된 값이 넘어온 경우 바로 깔끔하게 예외처리를 할 수 있다.
"오류는 가능한 한 빨리 발견하는 것이 좋다."
매개변수 검사를 제대로 하지 않았을 경우 다음 문제들이 발생할 수 있다.
메서드가 수행되는 중간에 모호한 예외를 던지며 실패하는 경우
메서드가 잘 수행됐지만 잘못된 결과를 반환하는 경우
메서드는 문제없이 수행됐지만, 어떤 객체를 이상한 상태로 만들어놓아, 미래의 알 수 없는 시점에 메서드와 관련 없는 오류를 발생하는 경우
public / protectd method
public 과 protected 메서드는 매개변수 값이 잘못됐을 때 던지는 예외를 문서화 해야한다. (@throws 자바독 태그 이용)
/** * (현재 값 mod m) 값을 반환 * 항상 음이 아닌 BigInteger를 반환한다는 점에서 remainder와 다름 * * @param m 계수(양수) * @return 현재 값 mod m * @throwsArithmeticException m이 0 이하이면 발생 */publicBigIntegermod(BigInteger m) {if (m.signum() <=0) {thrownewArithmeticException("계수(m)는 양수여야 합니다. "+ m); }return m; }
이렇게 발생하는 예외도 같이 문서화 해두면, 간단한 방법으로 API 사용자가 제약을 지킬 가능성이 높아진다. 위 예제에서 NullPointException 에 대한 문서화를 하지 않은 이유는 BigInteger 클래스 수준에서 기술되어 있기 때문이다. 클래스 수준 주석은 해당 클래스의 모든 public 메서드에 적용되므로, 각 메서드에 일일이 기술하지 않아도 된다.
Objects.requireNonNull
java7에 추가
java.util.Objects.requireNonNull
/** * Checks that the specified object reference is not {@code null}. This * method is designed primarily for doing parameter validation in methods * and constructors, as demonstrated below: * <blockquote><pre> * public Foo(Bar bar) { * this.bar = Objects.requireNonNull(bar); * } * </pre></blockquote> * * @param obj the object reference to check for nullity * @param <T> the type of the reference * @return {@code obj} if not {@code null} * @throwsNullPointerException if {@code obj} is {@code null} */publicstatic<T>TrequireNonNull(T obj) {if (obj ==null)thrownewNullPointerException();return obj; } /** * Checks that the specified object reference is not {@code null} and * throws a customized {@link NullPointerException} if it is. This method * is designed primarily for doing parameter validation in methods and * constructors with multiple parameters, as demonstrated below: * <blockquote><pre> * public Foo(Bar bar, Baz baz) { * this.bar = Objects.requireNonNull(bar, "bar must not be null"); * this.baz = Objects.requireNonNull(baz, "baz must not be null"); * } * </pre></blockquote> * * @param obj the object reference to check for nullity * @param message detail message to be used in the event that a {@code * NullPointerException} is thrown * @param <T> the type of the reference * @return {@code obj} if not {@code null} * @throwsNullPointerException if {@code obj} is {@code null} */publicstatic<T>TrequireNonNull(T obj,String message) {if (obj ==null)thrownewNullPointerException(message);return obj; }
null 검사를 수동으로 하지 않아도 된다.
원하는 예외 메세지도 지정할 수 있다.
입력 값을 그대로 반환해, 값을 사용하는 동시에 검사도 가능
this.strategy=Objects.requireNonNull(strategy,"전략 값이 없습니다.");
Java9 Objects 범위검사
Java9에서는 범위 검사 기능도 추가됐다.
checkFromIndexSize
checkFromToIndex
checkIndex
위 메서드들은 null 검사 메서드만큼 유연하지는 않다.
예외 메세지 지정불가능
리스트와 배열 전용으로 설계
닫힌 범위는 다루지 못함
private method
private 메서드의 경우 assert (단언문)을 사용해 매개변수 유효성을 검증할 수 있다.