아이템 49. 매개변수가 유효한지 검사하라 #114
Unanswered
Irisation23
asked this question in
3. 과제
Replies: 2 comments 3 replies
-
매개변수 유효성 검사는 사실 당연하게 하고있었던 것 같습니다. |
Beta Was this translation helpful? Give feedback.
0 replies
-
사실 실무하면서 javadoc으로 문서화하는 경우가,, 드문 거 같긴 하네요,,
이건 처음 알았네요,, |
Beta Was this translation helpful? Give feedback.
3 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
📝 구성
Table of contents generated with markdown-toc
1. 매개변수가 유효한지 검사하라
메서드와 생성자 대부분은 입력값이 특정 조건을 만족하기를 바란다.
위와 같이 이름을 관리하고 있는 클래스가 있고 관리하고 있는 이름의 인덱스값을 통해 값을 조회하는
getNameOf
가 있다고 가정한다. 이때index
가 음수이거나names
의 크기보다 크다면 에러가 발생한다.이런 제약은 반드시 문서화해야하며 메서드 바디가 실행되기 전에 검증을 해야한다.
오류를 발생한 시점에서 바로 잡지 못하면 해당 오류를 감지하기 어려워지고 오류의 발생 지점을 찾기 힘들어진다.
따라서 메서드 바디가 실행되기 전에 매개변수를 확인한다면 잘못된 값이 넘어왔을때 즉각적이고 깔끔한 방식으로 예외를 던질 수 있다.
2. 왜 매개변수를 검증해야 하는가?
매개변수 검증이 이뤄지지 않는다면 메서드가 실행되는 중간에 모호한 예외를 던지며 실패할 수 있다.
또는 메서드가 제대로 수행 되더라도 예상치 못한 결과를 도출할 수 있다.
특히 후자의 경우가 문제가 되는데 전자는 예외를 던지며 에러로그를 남기면 해결할 수 있지만, 후자는 실제 데이터 정합성이 깨진것을 확인했을때 인지가 가능하기 때문이다.
이렇게 매개변수 검증에 실패하면 실패하면 실패
원자성
을 어기는 결과가 나타난다.호출된 메서드가 실패하더라도 해당 객체는 호출 전의 상태를 유지해야한다.
3. 매개변수 검증 방법
3.1 public과 protected 메서드는 던지는 예외를 문서화해야한다.
public
과protected
는 외부 접근도가 높은 제어자이므로 이들 메서드에는@throws
Javadoc 태그를 통해 문서화해야한다.위는
BigInteger
의mod()
로 매개변수 m이 0 이하일때ArithmeticException
이 발생하는 것을@throws
Javadoc 태그로 명시하고 있다.public
,protected
이외에package pirvate
,private
는 개발자가 스스로 메서드가 호출되는 상황을 통제할 수 있다. 즉, 유효한 값이 들어온다는 것을 보장할 수 있다.3.2 assert
public
,protected
메서드 이외에는assert
단언문을 통해서 매개변수 유효성을 검증할 수 있다.assert
단언문은 자신이 선언한 조건이 무조건 참이어야 다음 로직을 수행한다.그렇지 않으면
AssertionException
을 던진다.assert
는 Java 실행시-ea 또는 --enableassertions
옵션을 주지않으면 런타임에 아무런 영향을 주지 않으며 성능 저하도 없다.보통 개발 중에 테스팅하는 목적으로 사용된다.
3.3 매개변수와 생성자
메서드에서 직접 사용하지는 않지만 나중에 사용하기 위해서
필드로 저장하는 경우
는 더더욱 철저히 검사가 필요하다. 이때 검사가 제대로 이뤄지지 않으면null
이 필드에 할당되거나 컬렉션이라면 컬렉션 안에null
이 들어갈 수 있다. 그리고 이null
을 사용함으로써NullPointerException
이 발생할 수 있다.NullPointerException
은 디버깅이 힘들다.생성자는 나중에 쓰려고 저장하는 매개변수의 유효성을 검사하라 원칙의 특수사례이다. 생성자 매개변수의 유효성 검사는 클래스 불변식을 어기는 객체가 만들어지지 않게 하는데 필수이다.
3.4 그외
유효성 검사 비용이 지나치게 높거나 실용적이지 않다면 예외적으로 유효성 검사에 대해 고려해 볼 수있다.
암묵적으로 유효성 검사를 하는 경우
Collection
의sort()
처럼 컬렉션에 들어있는 객체의 타입이 다르면ClassCastException
이 발생한다. 로직이 수행되면서 유효성에 어긋나는 경우Exception
을 던지므로 실행 전에 유효성 검사를 수행할 필요는 없다.다만, 암묵적 유효성 검사에 너무 의존하면 실패 원자성을 해칠 수 있다.
3.5 What about null parameters?
Effective Java에서는 Java 7에 추가된
java.util.Objects.requireNonNull
를 유연하고 사용하기 편한 메서드로 소개하고 있다.java.util.Objects.requireNonNull
도 결국에는 매개변수obj
가 null이라면 그대로NullPointerException
을 일으킨다.java.util.Objects.requireNonNull
을 활용한다면 다음과 같이 null일 때 default 값을 반환할 수 있도록 만들어 보는 활용 방안을 생각해 볼 수있다.Java9에는 requireNonNullElse 를 지원하여 Java API에서 지원한다.
4. 핵심 정리 📚
5. 회고 🧹
2023.02.11 토
Validation 그 끝은 어디인가 Front 편
을 담당했을 때 느낀점과는 사뭇 달랐다.@Valid
를 사용했던 기억이 나는데, 당시에는 왜 파라미터 단에서 먼저 검증하는 지에 대해 의문없이 사용했지만 이번 정리를 통해 유효성 검사는 빠르면 빠를 수록 좋다는 것을 알게 되었다.Beta Was this translation helpful? Give feedback.
All reactions