본문 바로가기
👨‍💻 프로그래밍/📦 Backend

Kotlin의 @JvmStatic 알아보기

by 개발자 진개미 2024. 8. 12.
반응형

사용법과 효과

평상시에는 @JvmStatic을 신경 쓸 필요가 전혀 없습니다. 하지만 Java와 Kotlin을 같이 써야 한다면 Kotlin이 어떤 식으로 컴파일되는지 알아야 하고, Java와 다른 점이 있다면 보정해 줘야 합니다. @JvmStatic은 Kotlin의 companion objectobject를 보정해 주기 위한 annotation입니다.

공식 문서를 보면 자세히 나와 있는데요.

 

Calling Kotlin from Java | Kotlin

 

kotlinlang.org

 

아래의 Kotlin 코드를 자바에서 호출한다고 하면...

class ExampleClass {
    companion object {
        fun exampleFunction() {}
    }
}

 

아래와 같이 해야만 동작합니다.

ExampleClass.exampleFunction(); // 동작 X
ExampleClass.Companion.exampleFunction(); // 동작 O

 

그 이유는 위 Kotlin Class는 Java로 치면 아래와 같이 컴파일 되기 때문입니다.

public final class ExampleClass {
    public static final ExampleClass.Companion Companion = new ExampleClass.Companion();

    public static final class Companion {
        public void exampleFunction() {}
    }
}

 

하지만 아래와 같이 이렇게 @JvmStatic을 붙이면... 

class ExampleClass {
    companion object {
        @JvmStatic
        fun exampleFunction() {}
    }
}

 

아래와 같이 컴파일 되서 Java의 static처럼 사용할 수 있습니다.

public final class ExampleClass {
    public static final ExampleClass.Companion Companion = new ExampleClass.Companion();

    public static final class Companion {
        public void exampleFunction() {}
    }

    public static void exampleFunction() {
        Companion.exampleFunction();
    }
}

 


Kotlin에서 companion classs와 object를 static class 안의 Instance 값으로 한 이유?

🐜 1 - 좀 더 객체지향적인 언어를 만들기 위해

Java의 static 함수/변수는 Class의 Instance가 아닌 그 Class 자체에 속해 있습니다. 이 자체가 객체지향적이지 않다는 주장이 있습니다. 객체지향이 뭐예요...? 하면... 뜨거운 기술적인 토론이 시작될 테지만 일단은 2가지로 줄이겠습니다.

  1. 모든 것은 객체로 모델링 돼야 한다. (객체 == 행동 + 상태)
  2. 다형성 (Polymorphism), 은닉성 (Encapsulation)

 

static은 개별 객체의 인스턴스가 아닌 객체 그 자체에 속해 있으니 객체로 모델링 된게 아닙니다. 또한 static 함수/변수는 일반적으로 Instance 변수에 접근이 불가능하니 객체는 상태를 외부에 감추고 직접 관리해야 한다는 은닉성은 당연히 깨집니다. 다형성도 static은 Runtime이 아니라 Compile Time에 확정되니 깨집니다.

 

🐜 2 - 더 많은 기능을 부여하기 위해

Java의 static은 객체지향에서 벗어나 있기 때문에 여러 기능들을 쓸 수 없습니다. Kotlin의 companion object나 object는 인스턴스이기 때문에 이런 제약이 사라집니다. 대표적으로...

  • interface를 implement하기
  • 상속
  • State를 가지기
  • JVM 이외의 대상으로 컴파일하기 (static 개념이 없는 런타임의 경우)

물론 이것들이 가능하다고 companion object와 object에 이것들을 해야 한다는 의미는 아닙니다. 🥲 (제발 하지 말아 주세요... 🥹)


반응형