在Kotlin中创建注释实例

Cla*_*scu 5 kotlin

我有一个用Java编写的框架,该框架使用反射来获取批注中的字段并根据它们做出一些决策。在某些时候,我还可以创建注释的临时实例并自己设置字段。这部分看起来像这样:

public @interface ThirdPartyAnnotation{
    String foo();
}

class MyApp{
    ThirdPartyAnnotation getInstanceOfAnnotation(final String foo)
        {
            ThirdPartyAnnotation annotation = new ThirdPartyAnnotation()
            {
                @Override
                public String foo()
                {
                    return foo;
                }

            }; 
            return annotation;
        }
}
Run Code Online (Sandbox Code Playgroud)

现在,我正在尝试在Kotlin中做确切的事情。请记住,注释位于第三方jar中。无论如何,这是我在Kotlin中尝试的方法:

class MyApp{
               fun getAnnotationInstance(fooString:String):ThirdPartyAnnotation{
                    return ThirdPartyAnnotation(){
                        override fun foo=fooString
                }
    }
Run Code Online (Sandbox Code Playgroud)

但是编译器抱怨:注释类无法实例化

所以问题是:我应该如何在Kotlin中这样做?

Кла*_*арц 7

您可以使用 Kotlin 反射来做到这一点:

val annotation = ThirdPartyAnnotation::class.constructors.first().call("fooValue")
Run Code Online (Sandbox Code Playgroud)

如果注释具有无参数构造函数(例如每个注释字段都有默认值),您可以使用以下方法:

annotation class SomeAnnotation(
        val someField: Boolean = false,
)
val annotation = SomeAnnotation::class.createInstance()
Run Code Online (Sandbox Code Playgroud)


Cla*_*scu 3

这是我可能找到的解决方案,但对我来说感觉像是一个黑客,我更希望能够在语言中解决它。无论如何,对于值得的事情,它是这样的:

class MyApp {
    fun getInstanceOfAnnotation(foo: String): ThirdPartyAnnotation {
        val annotationListener = object : InvocationHandler {
            override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any? {
                return when (method?.name) {
                    "foo" -> foo
                    else -> FindBy::class.java
                }
            }
        }
        return Proxy.newProxyInstance(ThirdPartyAnnotation::class.java.classLoader, arrayOf(ThirdPartyAnnotation::class.java), annotationListener) as ThirdPartyAnnotation
    }
}
Run Code Online (Sandbox Code Playgroud)