면접 질문실전 질문꼬리 질문

코틀린의 Backing Field와 Backing Property

skydovesJaewoong Eum (skydoves)||7분 소요

코틀린의 Backing Field와 Backing Property

Kotlin 프로퍼티는 접근자(accessor)를 포함하는 필드를 간결한 문법으로 선언할 수 있게 해줍니다. 이 문법 뒤편에서는 프로퍼티 값의 실제 저장을 관리하는 두 가지 메커니즘이 존재합니다. 바로 backing fieldbacking property입니다.

backing field는 프로퍼티가 커스텀 접근자에서 field 키워드를 사용할 때 컴파일러가 암묵적으로 생성하는 저장용 변수입니다. 반면 backing property는 값을 저장하는 별도의 private 변수를 명시적으로 선언하고, 공개 프로퍼티를 통해 제어된 접근만 노출하는 패턴입니다.

이 두 가지의 차이를 정확히 이해하면 관용적인(idiomatic) Kotlin 코드를 작성하고 캡슐화(encapsulation)에 대한 올바른 판단을 내리는 데 큰 도움이 됩니다. 특히 안드로이드 면접에서도 자주 등장하는 주제이므로 확실히 정리해 두시길 권장합니다. 이 글을 끝까지 읽으시면 다음 내용을 확실히 이해하실 수 있습니다.

  • Kotlin 컴파일러가 프로퍼티에 backing field를 생성하는 조건
  • 커스텀 getter/setter에서 field 식별자를 활용하여 backing field에 접근하는 방법
  • 고급 캡슐화 패턴을 위해 backing property를 구현하는 방법
  • ViewModel에서 StateFlowbacking property로 노출하는 일반적인 패턴

Backing Field

backing field는 프로퍼티의 접근자가 field 키워드를 사용할 때 Kotlin 컴파일러가 암묵적으로 생성하는 저장용 변수입니다. 프로퍼티의 실제 값을 보관하며, getter와 setter 내부에서만 접근할 수 있습니다.

var name: String = "Default"
    get() = field.uppercase() // 대문자로 변환하여 반환
    set(value) {
        field = value.trim() // 앞뒤 공백을 제거한 후 저장
    }

위 예제에서 field는 원시 String 값을 보관하는 backing field를 가리킵니다. getter는 값을 대문자로 변환하여 반환하고, setter는 공백을 제거한 후 저장합니다. 만약 field 키워드 없이 접근자 내부에서 프로퍼티 이름 자체를 사용하면 무한 재귀(infinite recursion)가 발생하므로 주의해야 합니다.

컴파일러는 backing field가 실제로 필요한 경우에만 생성합니다. field를 참조하지 않고 초기화 값(initializer)도 없는 커스텀 getter를 가진 프로퍼티에는 backing field가 생성되지 않습니다.

val fullName: String
    get() = "$firstName $lastName"  // backing field가 생성되지 않음

위처럼 다른 프로퍼티를 조합하여 값을 계산하는 프로퍼티는 별도의 저장 공간이 필요 없으므로, 컴파일러가 backing field 생성을 생략합니다. 이 경우 프로퍼티는 클래스 인스턴스에서 메모리를 차지하지 않으며, 매번 접근할 때마다 계산이 수행됩니다.

Backing Property

backing property는 실제 데이터를 저장하는 private 변수를 명시적으로 선언하고, 별도의 공개 프로퍼티를 통해 읽기/쓰기 접근을 제어하는 패턴입니다. 내부 표현(internal representation)과 외부에 노출되는 API를 완전히 분리할 수 있다는 것이 핵심 장점입니다.

private var _age: Int = 0

var age: Int
    get() = _age
    set(value) {
        if (value >= 0) _age = value // 음수 값은 무시
    }

위 코드에서 _age 프로퍼티가 backing property입니다. 실제 값을 보관하며 클래스 내부에서만 접근할 수 있습니다. 공개 프로퍼티인 age는 커스텀 접근자를 통해 _age에 위임(delegate)하면서, setter에 유효성 검증 로직을 추가하고 있습니다.

이 면접 질문은 구독자 전용입니다

Dove Letter를 구독하시면 안드로이드, 코틀린 개발 관련 독점 면접 질문의 전체 내용을 볼 수 있습니다.

구독하기