본문 바로가기
안드로이드/자바

requireContext() vs getContext()

by 나이아카 2022. 5. 10.

 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를 어떻게든 호출해주는 줄 알고 사용하다 큰 코 다치지 말고 예외처리를 했으면 하는 바람에서 씁니다만, 사실 이 글을 본다는 건 이미 터졌다는 의미겠죠...

댓글