최근 우아한테크코스에서 코틀린에 대해 공부하면서 상수를 관리할 때 companion object(동반 객체) 내에 필요한 상수를 선언하는 일이 자주 있었습니다.
단순히 상수이기 때문에 val 키워드를 사용하면 된다고 생각했지만, IDE에서는 이 방식을 추천하지 않았습니다.
val만 사용하여 상수를 선언하면, Might be 'const'라는 문구가 나타나면서 노란 줄로 경고가 나타납니다.
여기서 IDE가 추천해주는 방식을 따르면 const 키워드가 추가로 붙게 됩니다.
이 둘에 어떤 차이가 있는지 알아본 바로는,
const val는 컴파일 시점에 값을 할당하는 반면,
val는 런타임 시점에 값을 할당한다는 차이가 있습니다.
많은 레퍼런스를 참조해봤지만 대부분 이 둘에 대한 차이밖에 찾을 수 없었으며, Kotlin에서 이것이 가장 큰 차이점이라고 답해주었습니다.
그렇다면 여기서 한 가지 궁금한 점이 생길 수 있습니다.
대체 컴파일 시점과 런타임 시점에 값을 할당하는 것이 어떤 차이가 있을까?
우선, 컴파일 시점에 값을 할당하면 컴파일러는 해당 상수가 가지고 있는 값을 미리 알 수 있다는 장점이 있습니다.
아래 코드를 살펴보면 쉽게 이해할 수 있습니다.
// val 키워드를 통해 상수를 선언
object Constants {
val NAME = "BuNa"
}
// Kotlin
fun testValWithoutConst() {
val name = Constants.NAME
}
// Java
public final void testValWithoutConst() {
String name = Constants.INSTANCE.getNAME();
}
우선, val 키워드를 통해 상수를 선언하고 외부에서 값을 참조하는 코드를 작성해 보았습니다.
Kotlin을 Java로 디컴파일하여 확인해 보니, "BuNa"라는 값을 가지고 있는 NAME 상수에 접근하는 모습을 확인할 수 있습니다.
// val 키워드를 통해 상수를 선언
object Constants {
const val NAME = "BuNa"
}
// Kotlin
fun testValWithoutConst() {
val name = Constants.NAME
}
// Decompiled Java
public final void testValWithoutConst() {
String name = "BuNa"
}
그럼 이제, const val 키워드를 사용한 코드를 확인해 보겠습니다.
Kotlin을 Java로 디컴파일한 결과, 참조하는 쪽에서 NAME 상수에 직접 접근하지 않고, "BuNa"라는 literal string을 직접 가지고 있음을 확인할 수 있습니다.
컴파일러는 컴파일 시점에 이미 NAME 상수가 어떤 값을 가지고 있는지 알 수 있기 때문에, 값으로 대체가 가능합니다.
NAME이 "BuNa"로 인라인 되면서, 값을 참조할 때마다 상수에 접근하면서 발생하는 오버헤드를 줄일 수 있다는 장점을 가질 수 있습니다.
이것이 Kotlin에서 const 키워드를 사용하는 장점입니다.
해당 포스팅 내용에 오류가 있다면 댓글로 남겨주세요 :)
github : https://github.com/tmdgh1592
'Programming > Kotlin' 카테고리의 다른 글
[Kotlin] Jvm Prefix Annotation 5가지 파헤치기 (1) | 2023.04.05 |
---|---|
[Kotlin] Value Class (inline class deprecated) (2) | 2023.02.21 |
[Kotlin] val a: Int = 1000과 val b: Int = 1000은 다르다 (2) | 2023.02.20 |