728x90
Backing field
class User(name: String) {
var name: String = name
get() = name
set(value) {name = value}
}
위와 같은 클래스가 있다고 할 때, 코틀린에서 해당 property를 get 혹은 set 할 때 재귀호출이 일어나게 된다.
public fun main(){
println(User("mj").name)
User("mj").name = "jyami"
}
위와 같이 name 프로퍼티를 접근하는 것이 getter를 부르는 것과 같기 때문에
결국get() = this.get()
과 같이, getter를 부르면서 다시 getter를 호출하는 것과 같다.
마찬가지로 name 프로퍼티를 할당하는 것도 setter를 부르는 것과 같아서. set()=this.set("jyami")
다시 setter를 호출하게 된다.
따라서 getter, setter 모두 본인의 필드를 참조하는 경우에는 StackOverflowException
을 발생시키게 된다. 친절하게도 intellij 에서는 recursive call 이라고 안내를 해주고 있다.
추가로 kotlin을 kotlinc를 사용하여 생성된 바이트코드를 보면 어떤 경우에 backing field가 생성되는지를 볼 수 있다. 즉 backing field가 인스턴스 변수로 생성되는 경우는 아래와 같다.
- 하나이상의 기본 접근자를 사용하는 경우 (getter, setter)
- 커스텀하게 만든 접근자에서
field
를 사용하는 경우.
data class HttpResponse(val body: String, var headers: Map<String, String>) {
val hasBody: Boolean
get() = body.isNotBlank()
var statusCode: Int = 100
set(value) {
if (value in 100..599) field = value
}
}
body, header는 기본 접근자를 이유로, statusCode는 커스텀 접근자를 이유로 생성되는데, hasBody는 그렇지 않다. (필드로 생성되지 않는다.)
javap -c -p com.kakao.talk.HttpResponse
Compiled from "BackingField.kt"
public final class com.jyami.HttpResponse {
private final java.lang.String body;
private java.util.Map<java.lang.String, java.lang.String> headers;
private int statusCode;
// 함수들의 어셈블러 코드
'Develop > Kotlin' 카테고리의 다른 글
Kotlin Void vs Unit vs Nothing (0) | 2022.05.02 |
---|---|
Ktor 찍먹하기 - 간단 HTTP API 작성 (1) | 2021.12.11 |