首页 文章

在Kotlin中创建一个注释实例

提问于
浏览
4

我有一个用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;
        }
}

现在我想在Kotlin做一些确切的事情 . 请记住,注释是在第三方jar中 . 无论如何,这是我在Kotlin尝试的方式:

class MyApp{
               fun getAnnotationInstance(fooString:String):ThirdPartyAnnotation{
                    return ThirdPartyAnnotation(){
                        override fun foo=fooString
                }
    }

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

所以问题是:我应该如何在Kotlin做到这一点?

2 回答

  • 0

    这是我可能找到的解决方案,但对我来说感觉像是一个黑客,我宁愿能够在语言中解决它 . 无论如何,值得的是,它是这样的:

    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
        }
    }
    
  • 2

    你可以用Kotlin反射做到这一点:

    val annotation = ThirdPartyAnnotation::class.constructors.first().call("fooValue")
    

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

    annotation class SomeAnnotation(
            val someField: Boolean = false,
    )
    val annotation = SomeAnnotation::class.createInstance()
    

相关问题