Skip to main content

Backing property

Backing Field

실제로 데이터를 저장하고 있으나 외부에서 직접 수 없는 field.
오로지 get() set() 메소드로만 컨트롤 할 수 있다.

Backing field includes initialized property with value. Kotlin generates get() and set() automatically declaring public variable using variable name

You must avoid use same variable name in get() and set() as shown below

class Human() {
var name = "khazix"
get() {
println("name is $name")
return name
}
}

⚠️ This code throw stackOverflowError
since call each other infinitely in get()

getter naming

How to solve this problem?

Use Backing field with field keyword instead of field name.

class Human() {
var name = "khazix"
get() {
// `field` keyword stores the value of `name` property
println("name is $field")
return field
}
}

Backing field field keyword is used only in get() and set() method.


Backing Property

외부로부터 접근 가능한 property 내부 동작은 Backing field 를 통해 구현한다.

Without backing property

class CustomerWithoutBacking(val name: String) {
val messages = mutableListOf<String>()

fun addMessage(message: String) {
this.messages.add(message)
}

@Test
internal fun `load message without backing property`() {
val customer = CustomerWithoutBacking("Karma")
customer.addMessage("하나 둘 셋")
customer.messages.clear() // Accidential deletion of data.
}
}

Backing property

class Customer(val name: String) {
// Backing field
private var _messages: MutableList<String>? = null

// Backing Property
val messages: MutableList<String>
get() {
if (_messages == null) {
_messages = loadMessages()
}
return _messages!!
}

fun addMessage(message: String) {
this.messages.add(message)
}

private fun loadMessages(): MutableList<String> =
mutableListOf(
"Initial Contact",
"Convinced them to use kotlin",
"Sold traning class. Sweet.",
).also { println("Loaded messages.") }
}
    @Test
internal fun `load message`() {
val customer = Customer("Falcon")
customer.addMessage("NNNNNKKK")
// Call also { println("Loaded messages.") }
println(customer.messages)
customer.addMessage("Go Kotlin")
// also statement is not called.
println(customer.messages)
}

Test code result

Conclusion

Backing field support get() set() mechanism.
You can set custom method with field keyword.

Backing property is used when want to do something that does not fit into this "implicit backing field" scheme.

Reference