requireContex는 non Null 타입인데, 어째 firebase analytics에서 자꾸만 NullPotionException이 발생했다고 알려줍니다. 기존 코드에서 사용하던 코드를 사용할 때, 항상 '이걸 쓰는데는 이유가 있겠지'하며 사용하던 습관이 자꾸만 발목을 잡는 것 같습니다. 그래서 kotlin에서 requireContext()와 context로 사용하는 requireContext()와 getContext()를 살펴보려 합니다.
@Nullable
public Context getContext() {
return mHost == null ? null : mHost.getContext();
}
@NonNull
public final Context requireContext() {
Context context = getContext();
if (context == null) {
throw new IllegalStateException("Fragment " + this + " not attached to a context.");
}
return context;
}
두 코드의 가장 큰 차이점은 nullable 여부입니다. 어노테이션을 통해 확인할 수 있겠지만, requireContext는 NonNull이고 getContext는 Nullable입니다. 이는 그저 반환값의 차이로, context를 불러올 수 없는 경우 그냥 null을 반환하는지, 아니면 throw를 통해 exception을 발생시키는지에 대한 차이인 것을 코드로도 확인이 가능합니다.
requireContext는 NonNull이니 Nullable하지 않는 파라미터를 넘길 때 사용하면 문제 없이 앱이 돌아갈거라고 생각할 수 있지만, 앱이 터지는 것은 똑같습니다. Nullable인 주제에 Nullable하지 않은 척 하는 친구일 뿐이죠. 사실 애플리케이션을 제작하면서 문제가 있다고 바로 펑하고 터지는 앱을 만들고 싶은 사람은 없을 것 같습니다.
결국 결론만 말하자면 둘은 동일한 코드입니다.(단지 exception을 일으키느냐, null을 반환하느냐의 차이입니다.) Null이 아님을 보장해준다고 생각하기 쉬운 requireContext를 쓰더라도 터지지 않는 것은 아니니 try-catch 구문을 이용하든, if(context == null)을 이용하든 context는 특정 상황에서 null이 될 수 있음을 기억하고(특히 쓰레드나 코루틴을 통한 비동기적인 코드를 작성하는 측면에서) 사용할 수 있다면 좋겠습니다.
코드만 보면 차라리 getContext가 문법을 확인하는 과정에서 알아차릴 수 있으니 훨씬 더 나은 코드일 수도 있다는 생각이 듭니다. NonNull 어노테이션을 가진 주제에 ISE를 일으킨다는게... 하지만 대충보면 NonNull 타입의 파라미터를 넣어야할 때, 간단하게 사용하기는 유용합니다. 그에 대한 책임은 개발자가 져야 하겠지만요...
이 글을 보는 사람들은 저처럼 멍청하게 내부적으로 context를 어떻게든 호출해주는 줄 알고 사용하다 큰 코 다치지 말고 예외처리를 했으면 하는 바람에서 씁니다만, 사실 이 글을 본다는 건 이미 터졌다는 의미겠죠...
'안드로이드 > 자바' 카테고리의 다른 글
스레드(Thread)란? (1) | 2022.08.26 |
---|---|
자바의 스트림에 대하여(2) - java 8 (0) | 2021.10.05 |
자바의 스트림에 대하여(1) - java 8 (0) | 2021.09.27 |
자바의 인터페이스란? (0) | 2021.08.10 |
(java) StringBuilder vs StringBuffer (0) | 2021.08.01 |
댓글