# 애노테이션과 리플렉션

## 애노테이션

- 코틀린에서 애노테이션을 사용하는 문법은 자바와 똑같지만 애노테이션을 선언할 때 사용하는 문법은 자바와 약간 다르다

- @Test
- @Deprecated

```kotlin
@Deprecated("Use removeAt(index) instead.", ReplaceWith("removeAt(index)"))
fun remove(index: Int)
const val TEST_TIMEOUT = 100L

@Test(timeout = TEST_TIMEOUT)
fun testMethod() {
    ...
}
대상 목록 설명
property 프로퍼티 전체. 자바에서 선언된 애노테이션에는 이 사용 지점 대상을 사용할 수 없다
field 프로퍼티에 의해 성성되는 (뒷받침하는) 필드
get 프로퍼티 게터
set 프로퍼티 세터
receiver 확장 함수나 프로퍼티의 수신 객체 파라미터
param 생성자 파라미터
setparam 세터 파라미터
delegate 위임 프로퍼티의 위임 인스턴스를 담아둔 필드
file 파일 안에 선언된 최상위 함수와 프로퍼티를 담아두는 클래스
애노테이션 설명
@JvmName 최상위 선언을 담는 클래스의 이름을 바궈주는 애노테이션
@Suppress (코틀린에서 애노테이션 인자로 클래스나 함수 선언이나 타입 외에 임의의 식을 허용) 컴파일러 경고를 무시
@Target(AnnotationTarget.PROPERTY)
annotation class JsonName(val name: String)
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.CLASS) // 메타애노테이션
annotation class Test(val name: String)
@Target(AnnotationTarget.ANNOTATION_CLASS)
annotaion class BindingAnnotation

@BindingAnnotaion
annotaion class MyBinding

import kotlin.reflect.KClass

annotation class DeserializeInterface(val targetClass: KClass<out Any>)

리플렉션


import kotlin.reflect.full.*
class Person(
    val name: String,
    val age: Int
)

fun main() {
    val person = Person("Alice", 29)
    val kClass = person.javaClass.kotlin // KClass<Person>의 인스턴스를 반환한다
    println(kClass.simpleName)
    kClass.memberProperties.forEach(println(it.name))
}

import kotlin.reflect.KCallable
import kotlin.reflect.KFunction
import kotlin.reflect.full.callSuspend

fun foo(x: Int) = println(x)

fun main() {
    val kFunction = ::foo
    kFunction.callSuspend(42)
}