<aside> 💡
이번 장에서는 메서드를 설계할 때 주의할 점들을 살펴본다. 구체적으로는 매개변수와 반환값을 어떻게 처리해야 하는지, 메서드 시그니처는 어떻게 설계해야 하는지, 문서화는 어떻게 해야 하는지를 다룬다. 이번 장의 내용 중 상당 부분은 메서드뿐 아니라 생성자에도 적용된다. 그리고 사용성, 견고성, 유연성에 집중할 것이다.
</aside>
메서드와 생성자의 입력 매개변수의 값은 특정 조건을 만족해야 한다. 이런 제약은 반드시 문서화해야하며 메서드 몸체가 시작되기 전에 검사해야 “오류는 가능한 한 빨리 잡아야 한다”는 일반 원칙에 부합한다. 또한 메서드 몸체가 실행되기 전에 매개변수를 확인한다면 잘못된 값이 넘어왔을 때 즉각적이고 깔끔한 방식으로 예외를 던질 수 있다.
메서드가 수행되는 중간에 모호한 예외를 던지며 실패 할 수 있다.
******더 나쁜 상황은 메서드가 잘 수행되지만 잘못된 결과를 반환할 때다.
다시 말해 매개변수 검사에 실패하면 **실패 원자성(아이템 76)
**을 어기는 결과를 낳을 수 있다.
@throws JavaDoc
을 사용하면 된다.
보통은 IllegalArgumentException
, IndexOutOfBoundsException
, NullPointerException
중 하나가 될 것이다.
전형적인 예시를 살펴보자.
/**
* (현재 값 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);
// ... (계산 수행)
}
해당 메서드는 m
이 null
이면 NullPointerException
을 던진다.
클래스 수준 주석은 각 메서드에 일일이 기술하는 것보다 훨씬 깔끔한 방법이다.
또한 @Nullable
이나 이와 비슷한 애너테이션을 사용할 수도 있지만 표준적인 방법은 아니다.
하지만 자바 7에 추가된 java.util.objects.requireNonNull 메서드는 유연하고 사용하기도 편하니, 더 이상 null 검사를 수동으로 하지 않아도 된다.
this.strategy = Objects.requireNonNull(strategy, "전략");
이처럼 반환값은 그냥 무시하고 필요한 곳 어디서든 순수한 null 검사 목적으로 사용해도 된다.
자바 9에서는 Objects에 범위 검사 기능도 더해졌다.
checkFromIndexSize
, checkFromToIndex
, checkIndex
라는 메서드들인데, 예외 메시지를 지정할 수 없고, 리스트와 배열 전용으로 설계되어서 이런 제약이 걸림돌이 되지 않을 경우 유용하고 편하게 사용할 수 있다.