[kotlin] default getter-setter of class property

나호영·2023년 3월 30일

클래스의 프로퍼티는 다음과 같은 특성을 가지고 있다.

  • val, var 키워드로 선언됨
  • 사용되기 전에 초기화 되어야 함
  • . operator로 참조됨
  • data hiding

data hiding에 대해 자세히 살펴보자.
코틀린은 프로퍼티가 정의되면 자동으로 디폴트 getter-setter를 생성한다. 이는 인스턴스의 프로퍼티를 . 연산자로 접근할 때, getter-setter를 자동으로 호출하여 사용한다. 자세히 말하자면 직접 메모리에 담겨있는 값에 접근하는 것이 아니라 중간에 getter-setter라는 인터페이스를 두어 데이터를 숨기는 것이다.

class MyClass(val myProperty: String) { ... }

 var myProperty: String = initialVaue
	  get() = field
	  set(value) {
	    field = value
	  }

위와 같이 primary constructor에 프로퍼티를 정의하면 코틀린이 자동으로 아래와 같은 getter-setter를 생성한다. 여기서 field는 프로퍼티의 backing field의 식별자, 즉 실제 메모리에 담겨있는 값을 의미한다. 이렇게 getter-setter를 호출해 값에 접근하거나 변경한다.

custom getter-setter

class Person(val firstName: String, val lastName: String) {
    var fullName:String = ""
	get() = "$firstName $lastName“
	set(value) {
        	val name = value.split(" ")
            firstName = name[0]
            lastName = name[1]
            field = value  //backing field to hold property value in memory 
    	}
}

위와 같이 프로퍼티를 선언하며 getter-setter를 커스텀하여 사용할 수 있다. 마찬가지로 클래스의 프로퍼티는 초기화해야 되기 때문에 ""로 초기화하고 getter setter를 위와 같이 정의하였다.

그렇다면 primary constructor에 선언된 프로퍼티들의 getter-setter는 어떻게 커스텀 할 수 있을까?

아쉽게도 직접적으로 할 수 없다. 다음과 같은 두가지 방법으로 간접적으로 커스텀이 가능하다.

class Car(speed: Int) {
    var speed = speed
        get() = field 
        set(value) {
            field = value
        }
}

primary constructor에 var/val 키워드를 사용하지 않는 파라미터(지역 변수)를 이용하는 법

fun main(args: Array<String>){
    val c = Car(30)
    print(c.speed)
}

class Car(@JvmField var speed: Int) {
    fun getSpeed() = speed
    fun setSpeed(value: Int) { speed = value }
}

JvmField 에노테이션을 이용하여 디폴트 getter-setter 생성을 막고 그대로 필드를 노출시키며, getter-setter를 따로 정의하는 방법
getSpeed 함수와 setSpeed 함수는 원래 코틀린이 자동으로 만들어 주었다.(getter-setter)

@JvmField
Instructs the Kotlin compiler not to generate getters/setters for this property and expose it as a field.

profile
공부 내용 기록

0개의 댓글