[Kotlin] 변수의 고급 기술(상수, lateinit, lazy) 설명 & 예제

728x90

기존의 var , val의 차이는 알고 있다 ( 할당된 객체를 바꿀 수 있는 지의 유무)
그러나 val에서 객내 내부의 속성을 변경 할 수 없는 것은 아니다
그러나 상수는 절대 변경 할 수 없다

상수

  • 절대 변경할 수 없는 값
    • const val CONST_A = 1234
  • String과 같은 기본 자료형으로만 가능
  • 클래스 객체들을 담는 것은 불가능
  • 클래스의 속성(field)이나 함수의 지역변수로는 사용 불가능
  • 반드시 companion object 안에서 사용하여 객체의 생성과 관계 없이 고정적인 값으로만 사용 됨
  • 이름은 의례적으로 대문자와 언더바만 사용 const val CONST_A = 1234

예제

fun main() {
    val foodCourt = FoodCourt()

    foodCourt.searchPrice(FoodCourt.FOOD_CREAM_PASTA)
    foodCourt.searchPrice(FoodCourt.FOOD_STEAK)
    foodCourt.searchPrice(FoodCourt.FOOD_PIZZA)
}

class FoodCourt {
    //이름을 받아 가격을 검색 : 이름 일람 필요 -> companion object
    fun searchPrice(foodName: String) {
        val price = when (foodName) {
            FOOD_CREAM_PASTA -> 13000
            FOOD_STEAK -> 25000
            FOOD_PIZZA -> 15000
            else -> 0
        }

        println("${foodName}의 가격은 ${price}원 입니다")
    }

    companion object {
        const val FOOD_CREAM_PASTA = "크림파스타"
        const val FOOD_STEAK = "스테이크"
        const val FOOD_PIZZA = "피자"
    }
}

변수 대신 상수를 사용하는 이유
변수를 사용하지 않고 굳이 상수를 이용하는 이유는 변수는 런타임시 객체를 생성하는데 시간이 더 소요되어 성능의 하락이 있기 때문 따라서 늘 고정적으로 사용할 값은 상수를 통해 객체의 생성없이 메모리에 값을 고정하여 사용함으로서 성능 향상 가능

lateinit (늦은 초기화)

코틀린에서는 변수를 선언할 때 객체를 바로 할당하지 않는 경우는 기본적으로 컴파일이 불가능 함, 그러나 경우에 따라서는 변수에 객체를 할당하는 것을 선언과 동시에 할 수 없을 떄도 있다. -> lateinit 사용 lateinit var a:Int
일단 변수만 선언하고 초기값의 할당은 나중에 할 수 있도록 하는 것

lateinit var 변수의 제한사항

  • 초기값 할당 전 까지 변수를 사용할 수 없음(에러 발생)
  • 기본 자료형에는 사용할 수 없음 (String에는 사용가능)
  • lateinit 변수의 '초기화'여부는 ::a.isInitialized 사용

예제

fun main() {
    val a = LateInitSample()

    //결과 : 기본값
    println(a.getLateInitText())

    //결과 : 새로 할당한 값
    a.text = "새로 할당한 값"
    println(a.getLateInitText())
}

class LateInitSample {
    lateinit var text: String

    fun getLateInitText(): String {
        if (::text.isInitialized) {
            return text
        } else {
            return "기본값"
        }
    }
}

lazy delegate properties (지연 대리자 속성)

변수를 사용하는 시점까지 초기화를 자동으로 늦춰주는 기능

  • val a: Int by lazy { 7 }
  • 선언시 즉시 객체를 생성 및 할당하여 변수를 초기화 하는 형태를 갖고는 있지만 실제 실행시에는 a를 사용 ex) println(a)이 시점에서 초기화 됨 -> 코드의 실행시간을 최적화
  • 람다 함수임으로 안에 여러가지 구문이 들어갈 수 도 있지만 가장 마지막값으로 할당 됨

예제

fun main() {

    val number: Int by lazy {
        println("초기화를 합니다")
        7 //초기값
    }

    println("코드를 시작합니다")
    println(number)
    println(number)
}

 

728x90

댓글

Designed by JB FACTORY