본문 바로가기

개발 노트/Kotlin

[kotlin]null 값에 대한 안정적인 처리 - Null Safety

- null은 항상 이슈의 중심에 있는데, null로 인해 프로그램 전체 혹은 앱 전체가 멈출 수 있다

 

- 프로그램이 멈출 수 있는 상황을 다음과 같이 코드로 만들어보겠다

class One {
    fun print() {
        Log.d("null_safety", "can you call me?")
    }
}

 

-> 1개의 메서드를 갖고있는 클래스를 만든다

 

var one: One
if (1 > 2){
    one = One()
}
one.print()

 

-> 그리고 onCreate() 메서드 안에서 다음과 같이 one 변수 하나를 선언하고, 타입으로 내가 만든 클래스를 지정해둔다

-> 그리고 특정 조건이 만족할 때만 선언한 변수에 생성자를 호출해서 저장해두는 조건문 if를 만든다

-> 그리고 변수를 통해, 해당 클래스의 메서드를 하나 호출한다

 

-> 위 코드에서는 1 > 2가 false이기 때문에 one 변수는 아무것도 없는 null 상태가 된다

-> 이 때 print 메서드를 호출하면 null 포인터 예외가 발생하면서 프로그램이 다운된다!!

-> 물론 위 코드는 안드로이드 스튜디오에서 오류를 발생시켜 컴파일되지 않도록 막아주지만, 코드의 양이 많아지면 이런 상황이 언제든지 발생할 수 있으며 Kotlin은 이런 상황을 방지하기 위해서 다양한 안전장치를 만들어 놓았다

=> 그 결과물이 Null Safety 이다!!

 

 

# null값 허용하기 : ?

var variable: String?

 

- Kotlin에서 지정하는 기본 변수는 모두 null이 입력되지 않는다

- 따라서 null 값을 입력하기 위해서는 변수를 선언할 때 타입 뒤에 ?(Nullable, 물음표)를 입력해야한다

 

 

 

# "변수"에 null 허용 설정하기 

 

var nullable: String? // 타입 다음에 물음표를 붙여서 null 값을 입력할 수 있습니다.
nullable = null

var notNullable: String
notNullable = null // 일반 변수에는 null을 입력할 수 없습니다.

 

-> 변수의 타입 뒤에 물음표를 붙이지 않으면null 값을 입력할 수 없다

-> null 예외를 발생시키고 싶지 않다면 기본형으로 선언한다

 

 

 

# "함수 파라미터"에 null 허용 설정하기 

 

- 안드로이드의 onCreate() 메서드의 Bundle 파라미터처럼 함수의 파라미터에도 null 허용 여부를 설정할 수 있다

- 함수의 파라미터가 null을 허용하려면, 해당 파라미터에 대해서 null 체크를 먼저 해야만 사용할 수 있다

fun nullParameter(str: String?){ // 파라미터 str에 null이 허용됨
    if (str != null) {    // null 체크를 해야 str 사용가능
        var length2 = str.length
    }
}

 

-> 위 코드처럼 str 파라미터를 조건문 if에서 null인지 아닌지 체크해야지만 사용할 수있다

 

 

# "함수 리턴 타입"에 null 허용 설정하기 

 

- 함수의 리턴 타입에도 물음표를 붙여서 null 허용 여부를 설정할 수 있다

fun nullReturn(): String? {
    return null
}

 

-> 함수의 리턴 타입에 Nullable이 지정되어 있지 않으면, null 값을 리턴할 수 없다

 

 

 

# 안전한 호출 : ?. 

  • 지금까지는 변수를 Nullable로 만들기 위해서 물음표를 사용했다
  • 이제는 ?.(Safe Call, 물음표와 온점)을 사용해서 null 체크를 좀 더 간결하게 하겠다
  • Nullable인 변수 다음에 ?.을 사용하면 해당 변수가 null일 경우에,    ?. 다음의 메서드나 프로퍼티를 호출하지 않는다
  • 다음 코드에서처럼 문자열의 길이를 반환하는 length 프로퍼티를 호출했는데 str 변수 자체가 null일 경우,  length 프로퍼티를 호출하지 않고 바로 null을 반환한다
fun testSafeCall(str: String?): Int? {
    // str이 null이면 length를 체크하지 않고 null을 반환합니다.
    var resultNull: Int? = str?.length
    return resultNull
}

 

-> 만약 Safe Call을 사용하지 않았는데 str 변수가 null이라면 프로그램은 다운된다

 

 

# null값 대체하기 : ?:

- 위에서 안전한 호출을 위해서 ?. (Safe call)을 사용했다

- 이제는 ?: (Elvis Operator, 물음표와 콜론)을 사용해서 원본 변수가 null일 때 넘겨줄 기본값을 설정해보겠다

 

fun testElvis(str: String?): Int {
    // length 오른쪽에 ?:을 사용하면 null일 경우 ?: 오른쪽의 값이 반환됩니다.
    var resultNonNull: Int = str?.length ?: 0
    return resultNonNull
}

 

-> Safe Call 다음에 호출되는 프로퍼티 뒤에 다시 ?:을 붙이고 0이라는 값을 표시했다

-> 이렇게 호출하면 str 변수가 null일 경우, 가장 뒤에 표시한 0을 반환한다 

 

 

 

- 핵심 요약!

   -  Nullable(?), Safe Call(?.), Elvis Operator(?:)를 구분하는 법

  • Nullable
  • 표기법: 선언하는 변수의 타입 다음에 ? 표기
  • 사용 목적: null을 입력받기 위해 사용

 

  • Safe Call
  • 표기법: 선언된 변수의 이름 다음에 ?. 표기
  • 사용 목적: null일 때 ?. 다음에 나오는 속성이나 명령어를 처리하지 않고 바로 null값 반환

 

  • Elvis Operator
  • 표기법: 선언된 변수의 이름 다음에 ?: 표기
  • 사용 목적: null일 때 ?: 다음에 나오는 값을 기본값으로 사용 (null값을 지정해줄 수 있음)

'개발 노트 > Kotlin' 카테고리의 다른 글

[kotlin]스코프 함수  (0) 2024.01.16
[kotlin]지연 초기화  (0) 2024.01.16
[kotlin]클래스와 설계  (0) 2024.01.16
[kotlin]함수  (0) 2024.01.16
[kotlin]반복문  (0) 2024.01.16