주니어 개발자님, 이거 NullPointerException 났는데요? 😱

두별·2023년 2월 23일
2

TIL

목록 보기
37/46
post-thumbnail

주니어 개발자가 많이 하는 실수로는 소스 날리기, 데이터 날리기 등등.. 다양하게 무서운 것들이 있겠지만 개인적으로 가장 많이 겪은 실수는 NullPointerException을 방지하지 못한 것이였습니다..
너무 기본적인 부분이라 자주 했던 실수다. 라고 말하는 것도 너무 민망하고 창피스럽지만요.
급하게 코딩을 하다보면 주니어 개발자가 아니여도 놓칠 수 있는 부분이긴 하지만
이런 예상 가능한 에러는 미리 방지하면서 코드를 짜는 것도 실력과 경험이니까요.
오늘은 스스로를 좀 반성해보면서 어떻게 해야 이런 실수를 조금이라도 덜 하고 방어적으로 코드를 짤 수 있을까 고민해보는 회고를 해보겠습니다. 😓

왜 Null체크를 안하는걸까? 🤔

이 닮의 이름은 핑계..

이런 기본중의 기본을 왜 안했냐고 스스로에게 한번 물어본다면..
사실, 개발하면서 인지하고 있을 때도 있었다.
'아, 여기 널포인트익셉션 발생할 수 있겠다. 분기처리 해야지'
하지만 ,, 급한 요구사항을 빠르게 개발하다보니 이것 저것 급한 비즈니스 코드들을 우선적으로 짜느라, 생각만 했던 null 방지는 잊혀지고 말았음,,
그렇게 에러가 발생하고 나서야 아차하는 순간들을 겪었다.
테스트나 디버깅이 부족했던 탓도 있지만 결국은 다 내가 꼼꼼하지 못했던 탓이다.
인지하고 있었다면 더더욱 그러면 안됐었는데,, ☆

실수를 줄이기 위해 어떻게 해야 할까?

개인적으로 필요하다고 느꼈던 것들은

1. 테스트 코드 작성

현재 회사에서는 테스트 코드를 작성하는 개발 문화가 없지만, 토이프로젝트 하면서 mocking을 활용한 단위 테스트 코드를 짬짬히 사용해 봤는데 확실히 예상하지 못한 에러를 방지하는데 도움이 되는 것을 느꼈다. 다양한 실패케이스를 생각하게 되다보니 타입으로 인해 발생하는 에러들을 좀 더 고려하게 되는 것 같다.

2. 코드 리뷰

열심히 코딩을 하다보면 시야가 좁아질 때가 있다. 이럴땐 다른 사람들의 시야를 빌려서 코드를 보는 것이 가장 좋다. 팀원들의 코드리뷰를 통해 내가 파악하지 못했거나 놓친 부분이 어떤 것이 있는지 알 수 있다.
신입 개발자는 이런 테스트 코드나 코드 리뷰 개발문화가 있는 회사로 간다면 코드 스킬이 금방 늘지 않을까 싶다.
실무에서 겪은 경험은 아니지만, 개인적으로 토이프로젝트 하면서 같이 하는 파트너겸 선생님께 코드리뷰를 받았는데 덕분에 놓쳤던 부분들을 한번씩 점검하게 되면서 코드 스킬이 많이 늘었던 것 같다.

3. Null을 방지하는 습관

  • 초기화를 null로 하지 않기
    디폴트값을 넣어줌으로써 메소드 호출시 발생하는 에러를 방지
  • 무의미한 null을 리턴하지 않기
    다른 코드에도 에러를 파생시킬 수 있으므로 주의가 필요함
  • null이 발생할 수 있는 데이터는 잊지 않고 null 체크
    데이터가 없다는 가정하에도 로직이 정상적으로 흐르도록 고려해야함
  • DB 컬럼 디폴트 값 설정해두기
    false, 0 이런 디폴트값 세팅 해둠으로써 null을 방지

4. Null 체크를 하는 다양한 방법

  • 아파치에서 제공하는 StringUtils
    Null 체크를 해주는 편리한 유틸이다. 빈값과 널체크를 같이 해주고 글자비교도 널체크를 같이 해주는 등 예외처리 할때 편리하다.
    ( isEmpty 메소드는 5.3부터 Deprecated 되어서 hasText를 사용 권장 )
    StringUtils.isEmpty("abc")
    StringUtils.hasText("abc")
  • Objcets isNull, nonNull
    분기 처리할때 != null 혹은 == null 보다 Objcets의 isNull(), nonNull() 메소드를 사용하는게 메소드명 자체로 의미가 더 명확하게 전달되어서 더 가독성이 좋다고 생각하는데 인터넷에 찾아보니 반대 의견인 경우도 있다.
    if (Objects.isNull(userDto)) {
       throw new AuthException("UserDto is null");
     }
  • equals() 비교 시 null이 아닌 문자열을 선행하여 비교
    "abc".equals(userName)
  • toString() 보다는 String.valueOf()를 사용
    String.valueOf(userName)
  • reference 타입보다는 primitive 타입을 사용
    int 같은 타입 변수는 기본형 변수로 null 값을 가질 수 없지만 (값이 없으면 0 반환)
    Integer 같은 객체, 참조형 변수는 null 값을 가질 수 있다.
  • Optional을 사용하는 방법도 있음
    값을 캡슐화 하는 Optional 클래스는 빈객체 인지 아닌지 체크하는 메소드들을 지원함
  • Spring은 DTO에 @NotNull을 사용
    API에서 필수적으로 받아야하는 파라미터 명시
    @NotNull(message = "userId is required")

느낀 점

어떤 방법으로 null 체크를 하든간에 중요한 것은 좀 더 꼼꼼하게 코드를 짜는 것이다. 어렵거나 못하는 것이 아니다. 좀 더 꼼꼼하면 해결할 수 있는 문제이니 항상 데이터가 다 있을거라는 생각을 하지말고 자주했던 실수인만큼 반복하지 말자! 화이팅 ~ 🐹🧀

참고

https://nhj12311.tistory.com/38
https://tjddnjs.tistory.com/123
https://technote-mezza.tistory.com/87
https://goddaehee.tistory.com/126
https://blog.naver.com/tmondev/220791552394
https://memo-the-day.tistory.com/97
https://incheol-jung.gitbook.io/docs/study/java-8-in-action/2020-03-10-java8inaction-chap10

0개의 댓글