Frudy
7k
2019-06-15 11:57:29 작성 2019-06-15 13:51:15 수정됨
0
754

제가 겪었던 NullPointerException의 상황들


혹시나~ Java 스택트레이스 보는법에 대해 알고싶으시면,

https://okky.kr/article/338405

fender님 게시글 참고하시면 되구요,


제가 겪어봤던 NullPointerException의 상황들을 나열해볼게요.

가장 기본적인 예외인만큼, 다른분들에게 도움이 되었으면 좋겠어요.



NullPointerException (이하 NPE)란,

null이 저장되어있는 변수로 객체에 접근하여

1. instance method를 실행할 때

2. instance field로 접근할 때 발생해요.


https://docs.oracle.com/javase/8/docs/api/java/lang/NullPointerException.html

자세한 내용은 여기서 확인이 가능해요.


1. 배열

첫번쨰 상황이에요. C에서도 비슷한 상황이 있죠.

이유는, new String[3];이, 3개의 String공간을 할당한게 아니기 때문이에요.


그래서,

strs[0] = null이 저장되어있고,

strs[1] = null이 저장되어있고,

strs[2] = null이 저장되어있기 때문에 그래요.


그러므로,

strs[0] = new String();

strs[1] = new String();

strs[2] = new String();

이렇게 배열안에 요소에 직접 새로 할당을 받아야 해요.


2. auto unboxing

Wrapper클래스를 배우신분들은, 아래의 코드가 잘 작동된다는것을 아실거에요.


그래서..! 아래와같은 상황에서는, NPE가 발생이 가능해요.


int num = (int)map.get("num"); 이 라인에서 NPE가 발생하려면,

겉으로만 봤을 때,

>> map = null이어야 get()메소드로 접근하다 NPE가 발생가능한 경우말고 없는대...?

>> 하지만 바로 위에서 map = new HashMap<>();으로 객체를 할당받았는대..?

이렇게 생각할 수 있어요.


이건, auto unboxing을 하는방법을 알면 쉽게 알수있어요.


네 바로 저 라인에서 NPE가 발생한것이지요.


우리가 굳이 Integer변수에 intValue()를 쓰지않아도,

int로 변환되는것을 auto unboxing이라고 하죠?

그래서 integer형 변수가 null이라면, 당연히 intValue()로 접근하다 NPE가 발생가능해요.


3. 향상된 for문

이처럼, 코드 겉으로만 봤을 때 NPE가 안보이는 경우가 한번 더 있었어요.


이것 역시 겉으로는 안보이지만,

enhanced for문은 내부적으로 이렇게 변환이 되기 때문에,

NPE가 충분히 발생할 수 있어요.



4. sendRedirect


세션에서 로그인정보를 가져와서, 없으면 로그인폼으로 리다이랙트 시키는 코드에요.

저 코드도, NPE가 발생할 수 있어요.


https://www.google.com/search?rlz=1C1ASUM_enKR764KR764&ei=j1sEXcXcEcj_8gX-zKnICw&q=sendRedirect+NullPointerException&oq=sendRedirect+NullPointerException


sendRedirect NullPointerException이라고 검색해보면 꽤 많은사람들이

이런 경우를 겪었다는것을 알수있어요.


이유는, response.sendRedirect() 이후에, 코드가 계속 실행되기 때문이에요.


그러므로, 반드시 response.sendRedirect()이후에, 곧바로 return; 같은걸 해야해요.

포워딩도 마찬가지로, 이후에 계속 코드가 실행되기 때문에, 주의가 필요해요.



5. Spring bean을 new연산자로 생성하는 경우

스프링을 배운지 얼마 안된 사람이 꽤 실수하는 예시인대요,

바로, bean을 가져올 떄,



이렇게 생성하는 경우에요..

그전에 항상 new객체로 생성해왔으니까요.

이럴경우, NPE가 발생할 가능성이 충분히있어요.


AnswerDao에서, 

sqlSessionTemplate.methodName( ~~ ) 이렇게 접근하기 때문에,


new연산자로 생성하게 될경우 sqlSessionTemplate을

@Autowired해오지 못하여,  sqlSessionTemplate = null이 되고,


sqlSessionTemplate.methodName( ~~ ) 여기서 NPE가 발생하게되요.


그러므로... 스프링에 빈으로 등록한 클래스는,

new연산자를 잘못쓰지않도록 조심해야해요.


평소에 버그나면 메모해뒀었는대, 지금보니 상황이 다양하네요?

NPE예방방법에 대해서도 작성해보려 했으나,

https://goddaehee.tistory.com/126 URL하나 남겨놓고 이만 줄이겠습니다.


즐거운 주말 보내세요!

0
  • 댓글 0

  • 로그인을 하시면 댓글을 등록할 수 있습니다.