
오늘 알아볼 내용은 const , jvmField에 관한 내용입니다.
아래의 코드를 디컴파일 해봅시다.
class jvmconstval {
var test = ""
}
위의 코드를 디컴파일 해보면, class안에 getter와 setter가 들어있습니다.
//decompile
public final class jvmconstval {
@NotNull
private String test = "";
@NotNull
public final String getTest() {
return this.test;
}
public final void setTest(@NotNull String var1) {
Intrinsics.checkNotNullParameter(var1, "<set-?>");
this.test = var1;
}
}
val은 어떨까요?
public final class jvmconstval {
@NotNull
private final String test = "";
@NotNull
public final String getTest() {
return this.test;
}
}
여기서 알아볼것은 Kotlin에서 Class는 open class가 되지 않는 이상, 상속을 할 수 없습니다.
그리고 상속을 할 경우에도, getter를 오버라이딩하지 못하기 위해 final 연산자가 사용됩니다.
val 변수로 선언되면, 변수에 final 연산자가 붙는데, 객체 값을 변경못하게 막습니다.
하지만 아래의 코드 같이 프로그래밍에 따라 값이 변경될 수도 있습니다.
//val인데도 갖고오는 값은 변경될 수 있음.
val str : String
get() {
return if (str.isEmpty()) {
"비었다"
} else {
"안비었다"
}
}
const 연산자는 컴파일시 할당되게 만듭니다.
연산자를 붙이게될경우, topLevel이나 object에만 사용할 수 있습니다.
const val test = ""
class jvmconstval {
val test = ""
}
public final class JvmconstvalKt {
@NotNull
public static final String test = "";
}
//const를 toplevel로 쓸경우, 새로운 클래스가 하나 더 생긴다.
package com.example.playground;
import kotlin.Metadata;
import org.jetbrains.annotations.NotNull;
public final class jvmconstval {
@NotNull
private final String test = "";
@NotNull
public final String getTest() {
return this.test;
}
}
그리고 컴파일될때, inlining이 일어납니다.
public final class JvmconstvalKt {
@NotNull
public static final String test1 = "밥줘";
}
public final class jvmconstval {
@NotNull
private final String test = "";
@NotNull
public final String getTest() {
return this.test;
}
public final void test() {
(new StringBuilder()).append("밥줘").append(this.test).toString();
}
}
Kotlin에서 선언하는 변수들은 기본적으로 getter와 setter 구조를 가집니다.
getter,setter를 제거하고 public 으로 바꾸고싶다면, @jvmField 어노테이션을 사용하면 됩니다.
class jvmconstval {
@JvmField
val test = ""
val test1 = ""
}
//decompile
public final class jvmconstval {
@JvmField
@NotNull
public final String test = ""; //얘는 public
@NotNull
private final String test1 = ""; // 얘는 private
@NotNull
public final String getTest1() {
return this.test1;
}
}
What can const val do which @JvmField val cannot?