Java 互操作:将@JvmName 应用于接口或抽象中属性的 getter class
Java Interop: Apply @JvmName to getters of properties in interface or abstract class
通常我们可以在kotlin中编写如下代码:
val hasValue : Boolean
@JvmName("hasValue") get() = true
这将为 Java interop.
生成方法 hasValue()
而不是 getHasValue()
但是,在一个界面中,这给了我一个编译错误:
val hasValue : Boolean
@JvmName("hasValue") get
抽象中的以下声明也是如此class:
abstract val hasValue : Boolean
@JvmName("hasValue") get
所以这是我的问题:如何告诉 kotlin 编译器使用 hasValue()
而不是 getHasValue()
作为 kotlin 接口中属性的 getter(和 setter)?
我认为 Kotlin 在 open
/override
property/function 上使用 @JvmName
有一些限制。禁止在open
/override
函数上使用@JvmName
可以避免在interface/superclass和子类上有不同的jvmName。
在下面的示例中,我尝试使用不同于接口 (hasValue
) 的 jvmName (hasValueImpl
) 注释覆盖的 属性 getter它给出了编译错误:
'@JvmName' annotation is not applicable to this declaration
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
}
事实证明,这是可能的:
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:
我无法理解。我确定这是有原因的。
有一个解决方法,请参阅:https://youtrack.jetbrains.com/issue/KT-31420
简单地用注释抑制这个 INAPPLICABLE_JVM_NAME
错误:@Suppress("INAPPLICABLE_JVM_NAME")
通常我们可以在kotlin中编写如下代码:
val hasValue : Boolean
@JvmName("hasValue") get() = true
这将为 Java interop.
生成方法hasValue()
而不是 getHasValue()
但是,在一个界面中,这给了我一个编译错误:
val hasValue : Boolean
@JvmName("hasValue") get
抽象中的以下声明也是如此class:
abstract val hasValue : Boolean
@JvmName("hasValue") get
所以这是我的问题:如何告诉 kotlin 编译器使用 hasValue()
而不是 getHasValue()
作为 kotlin 接口中属性的 getter(和 setter)?
我认为 Kotlin 在 open
/override
property/function 上使用 @JvmName
有一些限制。禁止在open
/override
函数上使用@JvmName
可以避免在interface/superclass和子类上有不同的jvmName。
在下面的示例中,我尝试使用不同于接口 (hasValue
) 的 jvmName (hasValueImpl
) 注释覆盖的 属性 getter它给出了编译错误:
'@JvmName' annotation is not applicable to this declaration
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
}
事实证明,这是可能的:
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:
我无法理解。我确定这是有原因的。
有一个解决方法,请参阅:https://youtrack.jetbrains.com/issue/KT-31420
简单地用注释抑制这个 INAPPLICABLE_JVM_NAME
错误:@Suppress("INAPPLICABLE_JVM_NAME")