package _z_additional
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import kotlin.reflect.KFunction
import kotlin.reflect.full.declaredMemberFunctions
import kotlin.reflect.jvm.reflect
/*https://stackoverflow.com/questions/63439469/how-to-obtain-an-annotation-of-a-function-literal-at-runtime*/
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
object _13_Reflection_ObtainingAnnotationOfAFunctionLiteral_Test {
@Target(AnnotationTarget.FUNCTION)
private annotation class A
//@formatter:off
@A private fun f1() {}
private val f2: () -> Unit = @A {}
private val f3: () -> Unit = @A fun() {}
//@formatter:on
@Test
fun demonstrate_usingReflect() {
listOf(::f1, f2.reflect(), f3.reflect()).filterNotNull().withIndex().forEach { (index, f) ->
println("[$index] Function name = ${f.name}")
println("[$index] Annotations = ${f.annotations.joinToString()}")
println()
}
}
@Test
fun demonstrate_usingClass() {
listOf(f2::class, f3::class).withIndex().forEach { (index, cls) ->
val invokeFunction: KFunction<*> = cls.declaredMemberFunctions.first {it.name == "invoke" && it.isOperator}
println("[$index] Function name = ${invokeFunction.name}")
println("[$index] Annotations = ${invokeFunction.annotations.joinToString()}")
println()
}
}
}
demonstrate_usingReflect
Output
[0] Function name = f1 [0] Annotations = @_z_additional._13_Reflection_ObtainingAnnotationOfAFunctionLiteral_Test$A()
[1] Function name = [1] Annotations =
[2] Function name = [2] Annotations =
demonstrate_usingClass
Error Output
java.lang.UnsupportedOperationException: This class is an internal synthetic class generated by the Kotlin compiler, such as an anonymous class for a lambda, a SAM wrapper, a callable reference, etc. It's not a Kotlin class or interface, so the reflection library has no idea what declarations does it have. Please use Java reflection to inspect this class: class _z_additional._13_Reflection_ObtainingAnnotationOfAFunctionLiteral_Test$f2$1