Java Interop:将@JvmName应用于接口或抽象类中的属性的getter

msr*_*rd0 9 java getter annotations interface kotlin

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

val hasValue : Boolean
    @JvmName("hasValue") get() = true
Run Code Online (Sandbox Code Playgroud)

这将生成的方法hasValue(),而不是getHasValue()针对Java的互操作.

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

val hasValue : Boolean
   @JvmName("hasValue") get
Run Code Online (Sandbox Code Playgroud)

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

abstract val hasValue : Boolean
    @JvmName("hasValue") get
Run Code Online (Sandbox Code Playgroud)

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

Nik*_*bko 12

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

只需INAPPLICABLE_JVM_NAME使用注释抑制此错误:@Suppress("INAPPLICABLE_JVM_NAME")


Jac*_*hoi 6

我认为科特林对使用一些限制@JvmNameopen/ override性能/功能.禁止使用@JvmNameon open/ overridefunction可以避免在接口/超类和子类上使用不同的jvmName.

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

'@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
}
Run Code Online (Sandbox Code Playgroud)

  • 你是对的,`@JvmName` 被禁止用于重写和可重写的函数。https://github.com/JetBrains/kotlin/blob/19e38bbc725ec68c9d40bc5c4ad8945266df7231/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/declarationCheckers.ktms#L141 回答正确,这应该被接受。 (2认同)

ret*_*vil 5

事实证明,这是可能的:

interface Foo {
    val bar: String
        @get:JvmName("getAwesomeBar") get
}
Run Code Online (Sandbox Code Playgroud)

然而,有趣的是这不起作用:

interface Foo {
    @get:JvmName("getAwesomeBar") 
    val bar: String
}
Run Code Online (Sandbox Code Playgroud)

但是,这确实有效:

class Foo {
    val bar: String
        @JvmName("getAwesomeBar") get() = "My bar value"
}
Run Code Online (Sandbox Code Playgroud)

这也有效!

class Foo {
    @get:JvmName("getAwesomeBar") 
    val bar: String
        get() = "My bar value"
}
Run Code Online (Sandbox Code Playgroud)

为什么get:在接口中执行此操作时需要额外的东西超出了我的范围。我相信这是有原因的。