10. 애노테이션과 리플렉션
- 애노테이션(annotation) 과 리플렉션(reflection) 을 사용하면 제약을 벗어나서 미리 알지 못하는 임의 클래스를 다룰 수 있습니다.
#
10.1 애노테이션 선언과 적용- 자바 프레임워크도 애노테션을 많이 사용하면, 코틀린 애노테이션도 개념은 마찬가지입니다.
- 메타데이터를 선언에 추가하면 애노테이션을 처리하는 도구가 컴파일 시점이나 실행 시점에 적절한 처리를 해줍니다.
#
10.1.1 애노테이션 적용- 코틀린은 자바와 같은 방법으로 애노테이션을 사용할 수 있습니다.
- 애노테이션의 인자로는 원시 타입의 값, 문자열, enum, 클래스 참조, 다른 애노테이션 클래스, 그리고 지금까지 말한 요소들로 이뤄진 배열이 들어갈 수 있습니다.
- 애노테이션 인자를 지정하는 문법은 자바와 약간 다릅니다.
- 클래스를 이노테이션 인자로 지정할 때는
@MyAnnotation(MyClass::class)
처럼::class
를 클래스 이름 뒤에 넣어야 합니다. - 다른 애노테이션을 인자로 지정할 때는 인자로 들어가는 애노테이션의 이름 앞에
@
를 넣지 않아야합니다. - 배열을 인자로 지정하려면
@RequestMapping(path = arrayOf("/foo", "/bar"))
처럼arrayOf
함수를 사용합니다.@JavaAnnotationWithArrayValue("abc", "foo", "bar")
처럼arrayOf
함수를 쓰지 않아도 됩니다.
- 클래스를 이노테이션 인자로 지정할 때는
- 애노테이션 인자를 컴파일 시점에 알 수 있어야 하므로, 임의의 프로퍼티를 인자로 지정할 수는 없습니다.
#
10.1.2 애노테이션 대상- 애노테이션을 붙일 때 이런 요소 중 어떤 요소에 애노테이션을 붙일지 표시할 필요가 있습니다.
- 사용 지점 대상(use-site target) 선언으로 애노테이션을 붙일 요소를 정할 수 있습니다.
- 사용 지점 대상을 지정할 때 지원하는 대상 목록은 다음과 같습니다.
이름 | 설명 |
---|---|
property | 프로퍼티 전체 |
field | 프로퍼티에 의해 생성되는 필드 |
get | 프로퍼티 게터 |
set | 프로퍼티 세터 |
receiver | 확장 함수나 프로퍼티의 수신 객체 파라미터 |
param | 생성자 파라미터 |
setparam | 세터 파라미터 |
delegate | 위임 프로퍼티의 위임 인스턴스를 담아둔 필드 |
file | 파일 안에 선언된 최상위 함수와 프로퍼티를 담아둔 클래스 |
#
10.1.3 애노테이션을 활용한 JSON 직렬화 제어- 직렬화(serialization) : 객체를 저장장치에 저장하거나 네트워크를 통해 전송하기 위해 텍스트나 이진 변환하는 것
- 역직렬화(deserialization) : 텍스트나 이진 형식으로 저장된 데이터로부터 원래의 객체를 만들어냅니다.
- 대표적인 예시로 사용하는
Jackson
과GSON
이 있습니다.
@JsonExclude
애노테이션을 사용하면 직렬화나 역직렬화 시 그 프로퍼티를 무시할 수 있습니다.@JsonName
애노테이션을 사용하면 프로퍼티를 표현하는 키/값 쌍의 키로 프로퍼티 이름 대신 애노테이션이 지정한 이름을 쓰게 할 수 있습니다.
#
10.1.4 애노테이션 선언- 가장 간단한 애토네이션은 파라미터도 없는 경우입니다.
annotation class JsonExclude
- 파라미터가 있는 애노테이션을 정의하려면 애노테이션 클래스의 주 생성자에 파라미터를 선언해야 함
annotation class JsonName(val name: Stirng)
- 자바의 애노테이션은 다음과 같습니다.
#
10.1.5 매타애노테이션: 애노테이션을 처리하는 방법 제어- 애노테이션 클래스에 적용할 수 있는 애노테이션을 메타애노테이션(meta-annotation) 이라고 부릅니다.
- 표준 라이브러리에 있는 메타애노테이션 중 가장 흔히 사용하는 메타애노테이션은
@Target
입니다.
- 메타애노테이션을 직접 만들어야한다면
ANNOTATION_CLASS
를 대상으로 지정합니다.
@Retention 애노테이션
- 정의 중인 애노테이션을 클래스를 소스 수준에서만 유지할지, .class 파일에 저장할지, 실행 시점에 리플렉션을 사용해 접근할 수 있게 할지를 지정하는 메타애노테이션
#
10.1.6 애노테이션 파라미터로 클래스 사용@DeserializeInterface
는 인터페이스 타입인 프로퍼티에 대한 역직렬화를 제어할 때 쓰는 애노테이션입니다.
KClass
는 자바java.lang.Class
타입과 같은 역할을 하는 코틀린 타입입니다.KClass
의 타입 파라미터는 이 KClass의 인스턴스가 가리키는 코틀린 타입을 지정합니다.
#
10.1.7 애노테이션 파라미터로 제네릭 클래스 받기CustomSerializer
애노테이션은 커스텀 직렬화 클래스에 대한 참조를 인자로 받습니다.- 이 직렬화 클래스는
ValueSerializer
인터페이스를 구현해야만 합니다.
serializationClass
파라미터의 타입에 대한 설명은 다음과 같습니다.
- 리플렉션을 사용해 애노테이션에 저장된 데이터에 접근할 수 있습니다.
#
10.2 리플렉션: 실행 시점에 코틀린 객체 내부 관찰- 리플렉션은 실행 시점에 객체의 프로퍼티와 메서드에 접근할 수 있게 해주는 방법
- 코틀린에서 리플렉션을 사용하려면 두 가지 서로 다른 리플렉션 API를 다뤄야 합니다.
- 첫번째는 자바가
java.lang.reflect
패키지를 통해 제공하는 표준 리플렉션 - 두번째는 코틀린이
kotlin.reflect
패키지를 통해 제공하는 코틀린 리플렉션 API
- 첫번째는 자바가