问题描述
我有一个带有 setter 的 Java 类,但没有属性的 getter。
class Person {
private String name;
public void setName(String name) { this.name = name; }
}
我想使用 .name=
从 Kotlin 分配给它
fun example() {
val p = Person()
p.name = "example"
}
我在尝试编译 Kotlin 时遇到错误 unresolved reference: name
。如果我添加 getter,错误就会消失,但是我可以将 setter 用作属性而不用在 Java 中定义 getter 吗?我知道我仍然可以从 kotlin 调用 p.setName("example")
。
以上是MCVE。 现实世界代码是一个带有setter而不是getter的Java构建器,我想在Kotlin中使用它,比如
val widget = WidgetBuilder().apply {
width = 1 // instead I need .setWidth(1)
height = 2
weight = 3
name = "my widget"
}.build()
解决方法
不,Kotlin 编译器仅在存在与 setter 具有相同或更高可见性的 getter 时才将其识别为属性。这是因为在 Kotlin 中没有没有 getter 的属性。 (See last sentence in this section.)
请注意,如果 Java 类只有一个 setter,它在 Kotlin 中作为属性不可见,因为 Kotlin 不支持 set-only 属性。
您可以为此类手动编写扩展属性,使您可以使用属性访问语法,尽管有些人可能会认为为属性设置非功能性 getter 是一种反模式。但是您可以控制扩展属性的可见性,因此可能没问题。
var WidgetBuilder.width: Int
@Deprecated("Getter is unsupported.",level = DeprecationLevel.ERROR)
get() = error("unsupported")
set(value) { setWidth(value) }
构建器的替代方法是使用您可能在其上设置的所有参数以及默认值制作单个扩展函数。然后,您可以使用 named arguments 获得与 apply
示例有些相似的语法。
FWIW,在使用 Java 构建器时,我只是按预期使用链式方法调用。