brunch

코틀린 Getters and Setters #2

빠르게 살펴보기

by 서준수

private set


외부에서 set을 할 수 없도록 하기 위해서 private set을 선언해줄 수 있습니다. 기본 setter의 구현을 변경할 필요가 없으면 body를 정의할 필요없이 접근자를 정의할 수 있습니다.


fun main() {

var student = Student()

//student.name = "Park" // 외부에서 set 불가

student.id = 200

println("student.id ${student.id} student.name ${student.name}")

student.printName()


}


class Student {

var id = 0

get() = 100

var name = "Suzuki"

private set


fun printName() {

this.name = "Park" // class 내부에서는 set 가능

println("this.name ${this.name}")

}

}


student.id 100 student.name Suzuki

this.name Park



Backing Fields


이전에 언급했던 getter와 setter을 생략하지 않고 선언하는 방법, 즉 custom 접근자를 작성할 때 backing field를 사용할 수 있습니다. 코틀린 클래스에서는 field를 가질 수 없지만 custom 접근자를 사용할 때 backing field가 필요한 경우가 있습니다. 이때 코틀린은 field라는 식별자를 사용하는 backing field를 제공합니다.

backing field가 없다면 어떤 문제가 있을까요? 다음의 코드를 보시면 이해가 빠를 것 같습니다.


코틀린


class Person() {

var id = 0

get() = 100

var name = "Suzuki"

set(value) { name = value }

}


여기까지 보면 얼핏 생각하기에 name에 value를 할당하여 제대로 set하는 것처럼 보입니다.


Java


public final void setName(@NotNull String value) {

Intrinsics.checkParameterIsNotNull(value, "value");

this.setName(value);

}


Java 코드를 보니 재귀함수가 보이고 무한루프에 빠져서 StackOverFlow가 발생할 것으로 보입니다.

아니나 다를까 다음과 같이 친절하게 알려줍니다.


99CCB3335A2D28BC1A346A StackOverFlow 발생 경고


그럼 field를 사용해봅시다.


코틀린


class Person() {

var id = 0

get() = 100

var name = "Suzuki"

set(value) { field = value }

}



Java


public final void setName(@NotNull String value) {

Intrinsics.checkParameterIsNotNull(value, "value");

this.name = value;

}


field 식별자는 오직 property 접근자에서만 사용할 수 있습니다. property를 위한 backing field는 적어도 하나 이상의 기본 접근자를 사용하거나 custom 접근자에서 field 식별자를 사용할 때 만들어집니다.


따라서 다음과 같은 경우에는 backing field가 없습니다.


val isEmpty: Boolean

get() = this.size == 0


참고로 코틀린 1.1 이후부터는 property type을 getter로부터 유추할 수 있다면 생략 가능합니다.


val isEmpty get() = this.size == 0 // type Boolean을 가짐


keyword
이전 07화코틀린 Getters and Setters #1