Java Interop:将@JvmName应用于接口或抽象类

时间:2017-11-27 05:09:13

标签: java interface annotations kotlin getter

通常,我们可以在kotlin中编写以下代码:

val hasValue : Boolean
    @JvmName("hasValue") get() = true

这将为 Java interop 生成方法hasValue(),而不是getHasValue()

但是,在接口中,这给了我一个编译错误:

val hasValue : Boolean
   @JvmName("hasValue") get

抽象类中的以下声明也是如此:

abstract val hasValue : Boolean
    @JvmName("hasValue") get

所以这是我的问题:如何告诉kotlin编译器在kotlin接口中使用hasValue()而不是getHasValue()来获取属性的getter(和setter)?

3 个答案:

答案 0 :(得分:9)

有一种解决方法,请参见:https://youtrack.jetbrains.com/issue/KT-31420

使用注释:INAPPLICABLE_JVM_NAME来简单地消除此@Suppress("INAPPLICABLE_JVM_NAME")错误

答案 1 :(得分:5)

我认为Kotlin在@JvmName / open属性/函数上使用override有一些限制。禁止在@JvmName / open函数上使用override可以避免在接口/超类和子类上使用不同的jvmName。

在下面的示例中,我尝试使用与接口(hasValueImpl)不同的jvmName(hasValue)来注释覆盖的属性getter,并且它会出现编译错误:

  

' @ JvmName'注释不适用于此声明

interface Abstract {

    @get:JvmName("hasValue")        //Compile error
    val hasValue: Boolean
        get() = false
}

open class Impl : Abstract {

    @get:JvmName("hasValueImpl")    //Compile error
    final override val hasValue: Boolean
        get() = false

    @get:JvmName("hasValue2")       //Compile error if hasValue2 is open
    val hasValue2: Boolean
        get() = false
}

答案 2 :(得分:1)

事实证明,这是可能的:

interface Foo {
    val bar: String
        @get:JvmName("getAwesomeBar") get
}

但是,有趣的是,这不起作用:

interface Foo {
    @get:JvmName("getAwesomeBar") 
    val bar: String
}

但是,这确实可行:

class Foo {
    val bar: String
        @JvmName("getAwesomeBar") get() = "My bar value"
}

这也可行!

class Foo {
    @get:JvmName("getAwesomeBar") 
    val bar: String
        get() = "My bar value"
}

在接口中执行此操作时,为什么需要额外的get:超出了我的范围。我确定是有原因的。