Java 파일을 Kotlin으로 리팩토링 하는 과정에서 JvmStatic 어노테이션이 자동으로 만들어지는 것을 확인할 수 있다.
@JvmStatic
은 static 변수의 get/set 함수를 자동으로 만들라는 의미이다.
다음 Animal 클래스에서 dog 변수를 companion object에 선언함으로써, 전역변수를 만들었다.
class Animal {
companion object {
var dogBark: String = "멍멍"
}
}
자바의 static 키워드는 클래스 멤버임을 지정하기 위해 사용하는데, 이때 static이 붙은 변수와 메소드를 각각 클래스 변수/ 클래스 메소드라 부른다.
반면, static이 붙지 않은 클래스 내의 변수와 메소드는 각각 인스턴스 변수, 인스턴스 메소드라 한다.
하지만 Kotlin에는 static이 없다!!!
companion object
라는 키워드와 함께 블록({}) 안에 멤버를 구성한다.
다시 Animal 클래스를 Java로 변환해보면 Animal.Companion 클래스에 getter/setter 가 존재하는 것을 볼 수 있다.
public final class Animal {
private static String dogBark = "멍멍";
public static final class Companion {
@NotNull
public final String getDogBark() {
return Animal.dogBark;
}
public final void setDogBark(@NotNull String var1) {
Intrinsics.checkNotNullParameter(var1, "<set-?>");
Animal.dogBark = var1;
}
}
}
자바에서 getDogBark를 사용하려면 Animal.getDogBark()와 같이 접근 할 수 없고, Animal.Companion.getDogBark()와 같이 접근해야한다. (불편)
다시 원점으로 돌아오면 @JvmStatic
는 Animal 바로 밑에 getter/setter함수가 생성되게끔 만들어준다.
아래 코틀린 코드는 dogBark를 선언할 때 @JvmStatic와 함께 선언했다.
class Animal {
companion object {
@JvmStatic
var dogBark: String = "멍멍"
}
}
위 코드를 자바 코드로 변환해보면
public final class Animal {
private static String dogBark = "멍멍";
public static final String getDogBark() {
return dogBark;
}
public static final void setDogBark(@NotNull String var0) {
dogBark = var0;
}
public static final class Companion {
public final String getDogBark() {
return Animal.dogBark;
}
public final void setDogBark(@NotNull String var1) {
Animal.dogBark = var1;
}
}
}
위 코드로 작성한다면 자바에서 Animal.Companion도 가능하지만 Animal.getDogBark 처럼 바로 접근이 가능해진다.
결론
@JvmStatic는 Companion에 등록된 변수를 자바의 static처럼 선언하기 위한 annotation이다.