• 코틀린 변수(프로퍼티) 초기화 init, lateinit, lazy에 대해서

    2022. 2. 27.

    by. 하루플스토리

    반응형

    안녕하세요, 하루플입니다.

     

    코틀린 변수를 프로퍼티라고 부른다고 했습니다.

     

    코틀린의 변수 프로퍼티(Property)와 일반 변수의 차이점

    안녕하세요, 하루플입니다. 코틀린의 변수를 프로퍼티라고 부릅니다. 그런데 일반적인 자바 변수를 프로퍼티라고 부르지는 않습니다. 단순한 변수 선언에도 자바와 코틀린에서 차이가 있다는

    haruple.tistory.com

    코틀린 언어는 정책적으로 NullPointerException을 예방하기 위해 안전장치를 해두었습니다.

    가장 대표적인 예가 변수(프로퍼티)는 무조건 값을 할당해야한다는 것이죠.

    //JAVA
    String name;

    자바의 경우 위 처럼 작성해도 에러가 발생하지 않지만 코틀린은 만약 var name : String 만 선언하면 에러가 발생합니다.

    아무런 값이 할당되지 않아 Null참조에러가 발생할 수 있기 때문이죠. 자바는 저렇게 값을 할당하지 않고 변수를 선언해도 되기 때문에 Null참조에러에 취약한 점을 가지고 있습니다. 코틀린은 이러한 NullPointerException을 진작에 막기위해 변수에 값을 선언하지 않으면 컴파일 할 수 없도록 되어있습니다.

     

    하지만 개발하다보면 자바처럼 변수만 먼저 선언하고 값을 나중에 할당하고 싶을 수도 있습니다.

    이처럼 변수를 나중에 초기화 하는 여러 방법을 알려드리겠습니다.

     

     

    1. 클래스 내부에 초기화 블록 선언

    class User {
        //프로퍼티에 값 할당 하지않고 선언
        var name: String
        var age: Int
        
        //초기화 블록 선언
        init{
            name = "haruple"
            age = 26
        }
    }

    이렇게 init블록 내부에 값을 선언하면 프로퍼티에 즉시 값을 할당하지 않아도 선언이 가능합니다. 초기화 블록은 객체를 생성할 때 가장 먼저 실행되기 때문에 가능한 방법입니다.

     

     

    2. ?를 사용해 Null 허용으로 선언

    코틀린 개발을 하다보면 변수 옆에 ? 가 선언된 것을 볼 수 있습니다. ?는 Null일 수도 있고 아닐수도 있다는 뜻입니다.

    var name: String? = null
    name = "haruple"

    이렇게 var 로 변수 오른쪽에 ?를 선언하면 null로 먼저 선언하고 나중에 변수에 값을 대입해줄 수 있습니다. 여기서 var과 val의 차이점을 아는 분들이라면 눈치 채셨겠지만 val로는 null로 선언을 할 수 없습니다. val은 처음에 null로 선언 후 값 변경이 불가능하기 때문입니다.

     

     

     

    3. lateinit을 사용해 나중에 값 초기화 하기

    늦은 초기화라는 뜻은 가진 'lateinit'을 사용하면 null로 초기화하지 않아도 나중에 초기화 할 수 있습니다.

    lateinit var name: String
    name = "haruple"

    말 그대로 늦게 초기화 하는 것을 허용해줌으로써 자바처럼 나중에 초기화가 가능하게 해줍니다. 이쯤에서 알 수 있는게 있습니다. 코틀린은 NullPointerException을 정말 싫어한다고요...

     

    그러니까 이렇게 늦게 초기화하는 모든 방법들은 정말 어쩔 수 없이 꼭 써야하는 경우에 쓰도록 합시다! 에러를 방지 하기 위함이라 권장하지 않는 방법이니까요. 위와 마찬가지로 val 변수는 늦은 초기화가 불가능 하니 참고해주세요.

     

     

     

     

    4. lazy를 사용해 프로퍼티가 사용되는 시점에 초기화 하기

    lazy를 쓰면 실제로 프로퍼티가 사용될 때 초기화를 할 수 있습니다.

    (참고! : 제가 계속 프로퍼티랑 변수를 혼용해서 헷갈릴 수 있는데 같은 뜻으로 사용하였고 코틀린에서는 정확히는 프로퍼티가 맞습니다!)

    class User{
        val name: String by lazy{
            "haruple"
        }
    
        val age: Int by lazy{
            26
        }
    }
    
    fun main(args: Arrays<String>){
        println("name : ${User.name}")
        println("age : ${User.age}")
    }

    만약 위 코드 처럼 lazy를 사용하면 print 구문에서 프로퍼티가 초기화되게 됩니다.

    반응형

    댓글