적절하게 null을 처리하라

null을 안전하게 처리하기

안전호출 printer?.print()

스마트 캐스팅 if(printer != null) printer.print()

엘비스 연산자

  printer?.name ?: "Unnamed"
  printer?.name ?: return
  printer?.name ?: throw Error("error")

Not-null assertion(!!)과 관련된 문제

!!문은 nullability가 제대로 표현되지 않는 라이브러리를 사용할 때 정도에만 사용해야함

미래에 코드가 어떻게 변화할지 모르니 현재 null이 아니라고 !!문을 쓰면 안된다.

!! 연산자 사용은 최대한 피하자

의심 없는 nullability 피하기

nullability를 안전하게 처리할 수 있는 함수 사용 -> List getOrNull

어떤 값이 클래스 생성 이후 확실하게 설정된다는 보장이 있으면 lateinit 프로퍼티와 notqnull 델리게이트를 사용

빈 컬렉션 대신 null을 리턴하지 마세요

nullable enum vs none enum

lateinit 프로퍼티와 notNull 델리게이트

lateinit 한정자는 프로퍼티가 이후에 설정될 것임을 명시하는 한정자 lateinit 선언이 되어있는데 초기화 안하고 사용시 예외발생

장점

언팩 하지 않아도 된다
이후에 어떤 의미를 나타내기 위해서 null을 사용하고 싶을 때, nullable로 만들 수 있음
프로퍼티가 초기화된 이후에는 초기화되지 않은 상태로 돌아갈 수 없다.

단점

Int,Long,Double,Boolean과 같은 기본 타입에 사용 불가
Delegates로 대체
var text: String by Delegates.notNull()
private class NotNullVar<T : Any>() : ReadWriteProperty<Any?, T> {
    private var value: T? = null

    public override fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return value ?: throw IllegalStateException("Property ${property.name} should be initialized before get.")
    }

    public override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        this.value = value
    }
}

notNull을 위임하면 get에서 널 검사를 진행한다.

Last updated