코틀린(Kotlin)

코틀린(kotlin) : Annotations 어노테이션

알통몬_ 2018. 2. 9. 09:00
반응형


공감 및 댓글은 포스팅 하는데

 아주아주 큰 힘이 됩니다!!

포스팅 내용이 찾아주신 분들께 

도움이 되길 바라며

더 깔끔하고 좋은 포스팅을 

만들어 나가겠습니다^^

 


Annotaions

Annotaion Declaration

어노테이션은 코드에 메타데이터를 붙인다는 의미입니다.

어노테이션을 선언할 때는 class 앞에 annotation 수정자를 붙여줘야 합니다.

annotation class Ano


Annotaion의 추가적인 속성은 annotaion class 에 meta-annotaion을 추가할 수 있습니다.

- @Target 은 주석으로 될 수 있는 element들을 지정합니다.(클래스, 메서드, 프로퍼티,

  표현 등등 )

- @Retention 주석이 컴파일 된 클래스 파일에 저장되는지 여부와 

런타임 시 반영을 통해 표시되는지 여부를 지정합니다. (기본적으로 둘 다 true)

- @Repeatable 은 단일 요소에서 동일한 주석을 여러 번 사용할 수 있도록 허용합니다.

- @MustBeDocumented 주석은 public API의 부분이고, generated API 문서에 표시된

class 나 method 서명에 포함되어야 한다고 지정합니다.


@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION,
AnnotationTarget.PROPERTY, AnnotationTarget.EXPRESSION,
AnnotationTarget.VALUE_PARAMETER)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class Ano

@Ano class AAA {
@Ano fun aaa(@Ano a : Int) : Int {
return (@Ano 10)
}
}

@Target에 포함된 속성들 앞에는 @Ano 어노테이션을 붙일 수 있습니다.


만약 클래스의 기본 생성자에 주석을 달고 싶다면 constructor 키워드 앞에

주석을 추가해주면 됩니다.

class BBB @Inject constructor(dependencyClass: DependencyClass){

}

또한 프로퍼티 접근자에도 주석을 달 수 있습니다.

class BBB {
var x: DependencyClass? = null
@Inject set
}


Constructors

주석은 파라미터가 있는 생성자를 가질 수 있습니다.


annotation class AAA(val name : String)

@AAA("altongmon") class BBB {

}

허용되는 파라미터 타입들

- 원시타입 Int, Long 등등

- String

- classes

- enum

- other annotation

- arrays of the types listed above. 위에 언급된 타입들의 배열


Annotation 파라미터는 nullable 타입을 가질 수 없습니다.

그 이유는 JVM에서 null을 annotation의 속성으로 저장할 수 있도록 지원하지

않기 때문입니다.


만약 Annotation이 다른 Annotation의 파라미터로 사용된다면

Annotation 앞에 @를 사용하지 않습니다.

fun main(args: Array<String>) {
@BBB("This function is deprecated, use === instead", AAA("this === other"))
val x = null

}

annotation class AAA(val name : String)

annotation class BBB (
val msg : String,
val aaa : AAA = AAA(""))


만약 annotaion의 argument로 클래스를 지정하고 싶을 경우에는 코틀린 클래스 KClass를

사용하면 됩니다.

코틀린 컴파일러가 Java Class로 자동 변환해줍니다, 그래서 자바 코드는 annotation과 

argument를 정상적으로 볼 수 있습니다.

fun main(args: Array<String>) {

@CCC(String :: class, Long :: class)
val a = 10

}
annotation class CCC(val arg1 : KClass<*>, val arg2 : KClass<out Any> )


Lambdas 람다

Annotation은 람다에서도 사용할 수 있습니다.

람다에서 annotation을 사용하면 람다 내부에서 호출되는 invoke() 메서드에 적용됩니다.

Quasar 같은 프레임워크에서 유용하게 사용됩니다.

val f = @Suspendable { Fiber.sleep(10)}


Annotation Use-site Targets

프로퍼티나 기본 생성자 파라미터에 Annotation을 사용할 때 코틀린 요소로부터

생성된 자바 요소가 있습니다, 따라서 자바 바이트 코드로 생성된 annotation이

위치할 수 있는 곳은 여러 군데입니다.

주석을 통해 무엇을 생성할 지 지정하려면 아래 예제처럼 하면 됩니다.

annotation class CCC

class DDD(@field:CCC val aaa : String,
@get:CCC val bbb : String,
@param:CCC val qqq : String)


동일한 구문을 사용해서 파일 전체에 주석을 달 수 있습니다.

파일의 가장 맨 위에 @file:JvmName("") 처럼 작성하면 됩니다.

패키지 선언 보다 위에 해야 합니다.

@file:JvmName("Example")

package org.mon.altong
fun main(args: Array<String>) {

}


동일한 타겟에 대해 여러 주석이 있다면, [] 괄호 안에 모든 주석을 넣어줌으로써

코드의 반복을 피할 수 있습니다.

class CCC {
@set:[Inject VisibleForTesting]
var aaa : String
}


타겟에 사용할 수 있도록 지원하는 모든 리스트입니다.

file, 

property(주석을 달면 java에서 볼 수 없습니다), 

field, 

get(property getter), 

set(property setter), 

receiver(), 

param(constructor parameter), 

setparam(property setter parameter),

delegate(the field storing the delegate instance for a delegated property)


확장 함수의 리시버 파라미터에 주석을 달려면 아래 구문을 사용하면 됩니다.

annotation class AAA

fun @receiver:AAA String.myExt(str : String) : String{
return str + "!!!"
}

만약 use-site target을 지정하지 않는다면 타겟은 사용된 @Target주석에 따라

선택됩니다.

적용 가능한 대상이 어려 개일 경우에는 아래 목록이 우선순위를 가집니다.

- param;

- property;

- field.


Java Annotations

자바 주석은 코틀린과 100% 호환 가능합니다.

https://kotlinlang.org/docs/reference/annotations.html#java-annotations

아래 링크에서 자세히 알아보실 수 있습니다.


이상입니다.

다음 포스팅에서는 Reflection에 대해 공부합니다.

감사합니다.

반응형