독서

[코틀린 인 액션] 10장. 애너테이션과 리플렉션

오렌지색 귤 2024. 5. 26. 20:54
반응형

찾아본 내용

 

1. 구체적인 프로퍼티에만 애너테이션 적용하기

 

아래와 같이 애너테이션을 사용하면 구체적인 프로퍼티에만 적용할 수 없다.

// kotlin
class User {
    @SomeAnnotation
    var name = "ABC"
}

 

 

아래와 같이 사용해야한다.

// kotlin
class User {
    @property:A
    @get:B
    @set:C
    @field:D
    @setparam:E
    var name = "ABC"
}

 

 

그러면 아래와 같이 컴파일된다.

// Compiles to the analog of the following Java code
public final class User {
    @D
    @NotNull
    private String name = "ABC";
    
    @A
    public static void getName$annotations() {
    }
    
    @B
    @NotNull
    public final String getName() {
        return this.name;
    }
    
    @C
    public final void setName(@E @NotNull String var1) {
        Intrinsics.checkNotNullParameter(var1, "<set-?>");
        this.name = var1;
    }
}

 

 

 

2. Static elements

 

코틀린에는 static elements의 개념이 없어서 object나 동반 객체 등을 사용한다.

// kotlin
class Money(val amount: BigDecimal, val currency: String) {
    companion object {
        fun usd(amount: Double) = 
            Money(amount.toBigDecimal(), "PLN")
    }
}

object MoneyUtils {
    fun parseMoney(text: String): Money = TODO()
}

fun main() {
    val m1 = Money.usd(10.0)
    val m2 = MoneyUtils.parseMoney("10 EUR")
}

 

 

하지만 자바에서 이들을 사용하기는 불편하다.

object를 사용하려면 static INSTANCE 필드를 사용해야한다.

// Java
public class JavaClass {
    public static void main(String[] args) {
        Money m1 = Money.Companion.usd(10.0);
        Money m2 = MoneyUtils.INSTANCE.parseMoney("10 EUR");
    }
}

 

 

이 문제를 해결하기 위해 JvmStatic 애너테이션을 사용하면 된다.

// Kotlin
class Money(val amount: BigDecimal, val currency: String) {
    companion object {
        @JvmStatic
        fun usd(amount: Double) =
            Money(amount.toBigDecimal(), "PLN")
    }
}

object MoneyUtils {
    @JvmStatic
    fun parseMoney(text: String): Money = TODO()
}

fun main() {
    val money1 = Money.usd(10.0)
    val money2 = MoneyUtils.parseMoney("10 EUR")
}
// Java
public class JavaClass {
    public static void main(String[] args) {
        Money m1 = Money.usd(10.0);
        Money m2 = MoneyUtils.parseMoney("10 EUR");
    }
}

 

 

 

3. JvmField

 

// Kotlin
class Box {
    var name = ""
}
// Java
public class JavaClass {
    public static void main(String[] args) {
        Box box = new Box();
        box.setName("ABC");
        System.out.println(box.getName());
    }
}

 

코틀린에서 선언한 var 프로퍼티는 기본적으로 private 백킹 필드와 public getter/setter를 생성한다.

자바에서 이를 접근하기 위해서는 필드에 직접 접근하는 것이 아니라, 생성된 getter와 setter 메서드를 통해 접근해야 한다.

 

// Kotlin
class Box {
    @JvmField
    var name = ""
}
// Java
public class JavaClass {
    public static void main(String[] args) {
        Box box = new Box();
        box.name = "ABC";
        System.out.println(box.name);
    }
}

 

JvmField 애너테이션 사용하면 자바 코드에서도 직접 접근이 가능해진다.

 

// Kotlin
object Box {
    @JvmField
    var name = ""
}
// Java
public class JavaClass {
    public static void main(String[] args) {
        Box.name = "ABC";
        System.out.println(Box.name);
    }
}

 

object나 companion object에 JvmField 애너테이션을 사용하면 필드 또한 static이 된다.

 

 

 

참고

https://kt.academy/article/ak-java-interop-2

 

반응형