회사에서 작성중인 안드로이드 코드가 거의 대부분 자바로 이루어져 있어 코틀린으로 변환하는 중에 있는데, 코틀린으로 작성할 때 상호작용하는 자바코드를 신경써야 하다보니 이것저것 많이 찾아보게 되는 것 같습니다. 이번에 시간이 남아 사용중인 것들을 하나씩 정리해야겠습니다.
@JvmStatic
이 어노테이션의 경우, java의 static처럼 사용할 수 있도록 도와주는 어노테이션입니다.
코틀린에서 객체를 선언하지 않고 바로 참조하는 static 형태의 경우 companion object 및 object 키워드를 통해 사용하곤 하는데, 이렇게 사용하는 경우 자바 코드에서는 Class.Companion.method 혹은 Class.INSTANCE.method 형태로 바꿔 사용해야 합니다.
코틀린에서는 큰 차이를 느끼지 못할 수 있어 괜찮지만, 만약 자바에서 기존에 static하게 사용하고 있었다면 자바 코드의 수정 없이 사용하기 위해서 @JvmStatic 어노테이션을 이용할 수 있습니다. 이 어노테이션을 사용하는 경우와 사용하지 않는 경우의 예를 보며 확인해보겠습니다.
class TestCase {
companion object {
var isTest : Boolean = false
var testCseCount : Int = 0
}
}
먼저 위와 같은 코틀린 코드를 자바로 변환하는 경우 어떤식으로 변환되는지 확인해보겠습니다.
public final class TestCase {
private static boolean isTest;
private static int testCseCount;
@NotNull
public static final Companion Companion = new Companion((DefaultConstructorMarker)null);
public static final class Companion {
public final boolean isTest() {
return TestCase.isTest;
}
public final void setTest(boolean var1) {
TestCase.isTest = var1;
}
public final int getTestCseCount() {
return TestCase.testCseCount;
}
public final void setTestCseCount(int var1) {
TestCase.testCseCount = var1;
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
위 코드에서 특이점은 Companion class가 생성되었고, 그 안에 getter/setter가 존재한다는 것입니다. 이는 자바 코드에서 TestCase.Companion.testCaseCount 형태로 사용해야한다는 것을 의미합니다.
class TestCase {
companion object {
@JvmStatic var isTest : Boolean = false
@JvmStatic var testCseCount : Int = 0
}
}
위의 코드는 자바로 변경하면 아래와 같습니다.
public final class TestCase {
private static boolean isTest;
private static int testCseCount;
@NotNull
public static final Companion Companion = new Companion((DefaultConstructorMarker)null);
public static final boolean isTest() {
Companion var10000 = Companion;
return isTest;
}
public static final void setTest(boolean var0) {
Companion var10000 = Companion;
isTest = var0;
}
public static final int getTestCseCount() {
Companion var10000 = Companion;
return testCseCount;
}
public static final void setTestCseCount(int var0) {
Companion var10000 = Companion;
testCseCount = var0;
}
public static final class Companion {
public final boolean isTest() {
return TestCase.isTest;
}
public final void setTest(boolean var1) {
TestCase.isTest = var1;
}
public final int getTestCseCount() {
return TestCase.testCseCount;
}
public final void setTestCseCount(int var1) {
TestCase.testCseCount = var1;
}
private Companion() {
}
// $FF: synthetic method
public Companion(DefaultConstructorMarker $constructor_marker) {
this();
}
}
}
두 코드의 가장 큰 차이점은 Companion 외부에 동일한 코드가 존재한다는 것입니다. 이는, 자바 코드에서 TestCase.isTest 형태로 작업이 가능하다는 것을 의미합니다. 기존에 자바 static을 사용하던 class의 syntax 수정 없이 사용할 수 있게 되었다는 것을 의미합니다.
거의 대부분 코틀린만 사용해서 안드로이드를 작업할 때에는 사실 코틀린 코드가 어떤식으로 자바로 디컴파일되는지 여부를 공부할 때 이외엔 잘 안찾아보게 되었는데, 자바로 된 코드가 남아 있어 코틀린과 혼용해서 써야 하는 상황이 오니 적극적으로 자바 코드로 어떻게 변형되는지를 찾게 되는 것 같습니다. 이렇게 자바와 코틀린이 어떻게 변형되는지 파악하면서 코딩하는 것도 좋은 경험이 되는 것 같습니다.
'안드로이드 > 코틀린' 카테고리의 다른 글
(Kotlin) Flow - 1 (0) | 2023.08.10 |
---|---|
AAC Navigation의 특징 (0) | 2023.06.02 |
Kotlin - Object 키워드(with SingleTon) (1) | 2023.02.17 |
Coroutine 관련 설명 글 링크 (0) | 2022.06.30 |
(Android) square - Retrofit (0) | 2022.05.18 |
댓글