使用反射读取 Kotlin 函数注释值?
Read Kotlin function annotation value using reflection?
给定这样的接口方法 (Android Retrofit),我如何在运行时从 Kotlin 代码读取注释参数中指定的 URL 路径?
ApiDefinition 接口:
@GET("/api/somepath/objects/")
fun getObjects(...)
读取注释值:
val method = ApiDefinition::getObjects.javaMethod
val verb = method!!.annotations[0].annotationClass.simpleName ?: ""
// verb contains "GET" as expected
// But how to get the path specified in the annotation?
val path = method!!.annotations[0].????????
更新 1
感谢您的回答。我仍在苦苦挣扎,因为我看不到要使用哪种类型来执行以下操作:
val apiMethod = ApiDefinition::getObjects
.. 然后将该函数引用传递给这样的方法(它被重用)
private fun getHttpPathFromAnnotation(method: Method?) : String {
val a = method!!.annotations[0].message
}
IntelliJ IDE 建议我使用 KFunction5<> 作为函数参数类型(据我所知它不存在)并且似乎要求我为该方法指定所有参数类型同样,这使得获取注释属性的通用调用变得不可能。难道没有 "Method" 的 Kotlin 等价物吗?一种接受任何方法的类型?我尝试了 KFunction,但没有成功。
更新 2
感谢您澄清问题。我已经到了这个地步:
ApiDefinition(改装界面)
@GET(API_ENDPOINT_LOCATIONS)
fun getLocations(@Header(API_HEADER_TIMESTAMP) timestamp: String,
@Header(API_HEADER_SIGNATURE) encryptedSignature: String,
@Header(API_HEADER_TOKEN) token: String,
@Header(API_HEADER_USERNAME) username: String
): Call<List<Location>>
检索注释参数的方法:
private fun <T> getHttpPathFromAnnotation(method: KFunction<T>) : String {
return method.annotations.filterIsInstance<GET>().get(0).value
}
调用以获取特定方法的路径参数:
val path = getHttpPathFromAnnotation<ApiDefinition>(ApiDefinition::getLocations as KFunction<ApiDefinition>)
似乎需要隐式转换或类型参数要求我提供 KFunction5 类型。
此代码有效,但它硬编码了 GET 注释,有没有办法让它更通用?我怀疑我可能需要寻找 GET、POST 和 PUT 以及 return 第一个匹配项。
使用 Kotlin KFunction
directly instead of javaMethod
(you're using Kotlin anyway!), and findAnnotation
编写简洁、惯用的代码。
如果注释恰好不是第一个,这也会起作用,其中 annotations[0]
可能会中断。
val method = ApiDefinition::getObjects
val annotation = method.findAnnotation<GET>() // Will be null if it doesn't exist
val path = annotation?.path
基本上findAnnotation
所做的就是return
annotations.filterIsInstance<T>().firstOrNull()
给定这样的接口方法 (Android Retrofit),我如何在运行时从 Kotlin 代码读取注释参数中指定的 URL 路径?
ApiDefinition 接口:
@GET("/api/somepath/objects/")
fun getObjects(...)
读取注释值:
val method = ApiDefinition::getObjects.javaMethod
val verb = method!!.annotations[0].annotationClass.simpleName ?: ""
// verb contains "GET" as expected
// But how to get the path specified in the annotation?
val path = method!!.annotations[0].????????
更新 1
感谢您的回答。我仍在苦苦挣扎,因为我看不到要使用哪种类型来执行以下操作:
val apiMethod = ApiDefinition::getObjects
.. 然后将该函数引用传递给这样的方法(它被重用)
private fun getHttpPathFromAnnotation(method: Method?) : String {
val a = method!!.annotations[0].message
}
IntelliJ IDE 建议我使用 KFunction5<> 作为函数参数类型(据我所知它不存在)并且似乎要求我为该方法指定所有参数类型同样,这使得获取注释属性的通用调用变得不可能。难道没有 "Method" 的 Kotlin 等价物吗?一种接受任何方法的类型?我尝试了 KFunction,但没有成功。
更新 2
感谢您澄清问题。我已经到了这个地步:
ApiDefinition(改装界面)
@GET(API_ENDPOINT_LOCATIONS)
fun getLocations(@Header(API_HEADER_TIMESTAMP) timestamp: String,
@Header(API_HEADER_SIGNATURE) encryptedSignature: String,
@Header(API_HEADER_TOKEN) token: String,
@Header(API_HEADER_USERNAME) username: String
): Call<List<Location>>
检索注释参数的方法:
private fun <T> getHttpPathFromAnnotation(method: KFunction<T>) : String {
return method.annotations.filterIsInstance<GET>().get(0).value
}
调用以获取特定方法的路径参数:
val path = getHttpPathFromAnnotation<ApiDefinition>(ApiDefinition::getLocations as KFunction<ApiDefinition>)
似乎需要隐式转换或类型参数要求我提供 KFunction5 类型。
此代码有效,但它硬编码了 GET 注释,有没有办法让它更通用?我怀疑我可能需要寻找 GET、POST 和 PUT 以及 return 第一个匹配项。
使用 Kotlin KFunction
directly instead of javaMethod
(you're using Kotlin anyway!), and findAnnotation
编写简洁、惯用的代码。
如果注释恰好不是第一个,这也会起作用,其中 annotations[0]
可能会中断。
val method = ApiDefinition::getObjects
val annotation = method.findAnnotation<GET>() // Will be null if it doesn't exist
val path = annotation?.path
基本上findAnnotation
所做的就是return
annotations.filterIsInstance<T>().firstOrNull()