본문 바로가기
프로그래밍 놀이터/Kotlin, Coroutine

[Effective Kotlin] Item 8 : Handle nulls properly

by 돼지왕 왕돼지 2022. 3. 5.
반응형

이 글은 Effective Java 를 완독하고, Kotlin 을 상용으로 사용하는 개발자 입장에서
Effective Kotlin 글 중 새로운 내용, remind 할 필요 있는 부분, 핵심 내용 등만 추려 정리한 내용입니다.

 

#
null 은 해석의 여지가 다분하기 때문에, 가능한한 의미가 명확해야 한다.

 

#
null 은 3가지 형태로 다뤄질 수 있다.

  1. ?., smart casting, elvis operator 등을 사용하여 안전하게 다루기
  2. error 던지기
  3. nonnull 로 refactor 하기

 

 

Handling nulls safely

 

 

Throw an error

#
null 이 아니어야만 하는 상황에서, null 일 경우 error 를 던짐으로써 programmer 가 예상하지 못한 상황을 발견할 수 있게 한다.
!!, requireNotNull, checkNotNull 등을 사용할 수 있다.

 

 

The problems with the not-null assertion !!

#
!! not-null assertion 은 부가정보가 적은 상태로 NPE 를 발생시키며, 코드속에 숨어 다음에 nullable 이 되는 case 등에서 버그를 찾아내기 어려운 상태로 만든다.

 

#
throw exception 도 사실은 나중에 nullable 로 바뀌는 경우 모든 케이스에 대처해야 한다는 점에서 마찬가지의 단점이 있지만, 부가정보를 더 넣을 수 있다는 장점이 !! not-null assertion 대비 있다.

 

#
!! not-null assertion 은 그 단점때문에 사용하지 않는 추세이다. 정적 코드 분석기를 사용하여 !! 가 있을 경우 error 를 뱉도록 하는 조직도 있다.

 

 

Avoiding meaningless nullability

#
class 가 List.get() 과 List.getOrNull() 처럼 여러 형태의 함수를 제공하거나,
sealed result class 를 대신 return 하여 null 을 제거하는 방법 등이 권장된다.

 

#
lateinit, notNull delegate 등을 사용하여 nonnull 로 만들어주는 방법도 있다.

 

#
null 대신 empty collection 등을 return 하는 것이 좋다.

 

#
Nullable enum 과 None enum 은 의미가 다르다.
null 은 스페셜한 케이스를 말한다.

 

 

lateinit property and notNull delegate

#
lateinit 은 사용할 때마다 null check 할 필요가 없고,
미래에 nullable 이 될 경우 쉽게 변경할 수 있으며,
한번 init 되면 uninit state 로 돌아갈 수 없다는 장점이 있다.

 

#
primitive type 의 경우는 lateinit 을 사용할 수 없어 Delegates.notNull 을 사용해야 한다. 이 방법은 조금 느리지만 primitive 들에 대해 lateinit 효과를 낼 수 있다.

private var aBoolean:Boolean by Delegates.notNull()

override fun onCreate(savedInstanceState: Bundle){
	super.onCreate(savedInstanceState)
	aBoolean = intent.getBooleanExtra(EXTRA_FLAG, false)
	// ..
}

다음과 같은 property delegate pattern 으로 교체될 수도 있다.

private var aBoolean:Boolean by arg(FROM_INTENT_BOOLEAN)

 

 

 

 

반응형

댓글