[TIL] Kotlin const val과 val의 차이점

곽태민·2026년 2월 26일

TIL

목록 보기
75/77

❓Kotlin에서 const val과 val의 차이점

Kotlin에서 const valval은 모두 재할당이 불가능한 값이다.
하지만 두 키워드는 컴파일 타임 상수 여부JVM 바이트코드 생성 방식에서 큰 차이가 있다.


1. val

val읽기 전용 프로퍼티 (read-only property) 이다.

val name = "John"
  • 재할당은 불가능
  • 하지만 컴파일 타임 상수가 아님
  • 런타임에 계산되는 값도 가능
val currentTime = System.currentTimeMillis()

2. const val 이란?

const val컴파일 타임 상수 (compile-time constant) 이다.

  • 반드시 val
    = top-level 또는 object / companion object 내부
  • primitive 타입 또는 String
  • getter 불가
  • 컴파일 시점에 값이 확정됨.
const val MAX_COUNT = 10

3. JVM 관점에서 차이

Kotlin은 JVM 위에서 동작하므로
결국 Java 바이트코드로 변환된다.

3.1 object 안에서 val 사용

object Constants {
	val NAME = "John"
}

Java로 디컴파일 할 경우

public final class Constants {
	@NotNull
    private static final String NAME = "John";
    
    @NotNull
    public final String getNAME() {
    	return NAME;
    }
    
    public static final Constants INSTANCE;
    
    static {
    	INSTANCE = new Constants();
    }
}

상수를 사용했을 때

println(Constants.NAME)

→ Java에서는

Constants.INSTANCE.getNAME();

즉,

  • getter 호출
  • INSTANCE 접근 필요
  • 값이 인라인되지 않음

3.2 object 안에서 const val 사용

object Constants {
	const val NAME = "John"
}

Java로 디컴파일 할 경우

public final class Constants {
	public static final String NAME = "John";
}

getter가 없다.

그리고 사용된 코드에서는

System.out.println("John");

→ 값이 직접 인라인이 되다.


4. 이런 차이가 발생하는 이유

const val은 JVM에서 다음과 같이 처리된다.

public static final

그리고 compile-time constant여서
사용하는 쪽 클래스의 constant pool에 값이 복사된다.

즉,

println(Constants.NAME)

은 실제 바이트코드에서

println("John");

이 된다.

반면 val

  • 객체 프로퍼티
  • getter 필요
  • INSTANCE 접근 필요
  • 인라인이 되지 않음

🤔 5. IDE가 const val을 추천하는 이유

IntelliJ에서 val보다 const val을 추천한다.

  • object 내부
  • primitive / String 타입
  • 값이 리터럴

이유는 아래와 같다.
1. 불필요한 getter 제거
2. INSTANCE 접근 제거
3. 바이트코드 단순화
4. 성능에 대한 이점
5. 어노테이션에서 사용 가능


profile
Node.js 백엔드 개발자입니다!

0개의 댓글