英文:
Ambiguous method call with JvmSynthetic setter
问题
class PersonBuilder {
@set:JvmSynthetic // 隐藏一个无返回值的 setter 方法,对 Java 客户端不可见
var age: Int? = null
@set:JvmSynthetic
var name: String? = null
fun setAge(age: Int?) = apply { this.age = age }
fun setName(name: String?) = apply { this.name = name }
fun build() = Person(age!!, name!!)
}
在 Java 一侧这样调用它:
```java
new PersonBuilder()
.setAge(22) // <- "error"
.setName("Peter")
.build();
它能够编译和运行,但是 Android Studio 显示错误 "模糊的方法调用。setAge (Integer) 在 PersonBuilder 中匹配",并且在这个 "错误" 后不提供任何自动建议和代码格式化。
英文:
I have a class with @JvmSynthetic
setters in order to provide only fluent builder-like setters for Java clients:
class PersonBuilder {
@set:JvmSynthetic // hide a void setter from Java
var age: Int? = null
@set:JvmSynthetic
var name: String? = null
fun setAge(age: Int?) = apply { this.age = age }
fun setName(name: String?) = apply { this.name = name }
fun build() = Person(age!!, name!!)
}
And call it like this on the Java side:
new PersonBuilder()
.setAge(22) // <- "error"
.setName("Peter")
.build();
It does compile & run, but Android Studio shows the error "Ambiguous method call. Both setAge (Integer) in PersonBuilder and setAge (Integer) in PersonBuilder match" and doesn't provide any auto-suggestions and code formating after this "error".
答案1
得分: 1
我认为没有必要使用@set:JvmSynthetic
标记,只需更改变量的可见性就可以了。尝试这样做:
class PersonBuilder {
private var age: Int? = null
private var name: String? = null
fun setAge(age: Int) = apply { this.age = age }
fun setName(name: String) = apply { this.name = name }
fun build() = Person(age!!, name!!) //注意潜在的空指针异常!
}
不管怎样,要小心build
函数。不能保证setAge
和setName
函数会在它之前被调用,所以可能会导致空指针异常。
更新
另一种通过保留@JvmSynthetic
来解决这个问题的方法是添加@JvmField
标记。更多信息请参阅这篇文章。
英文:
I believe there is no need to use the @set:JvmSynthetic
notation, just changing the visibility of variables should do the trick. Try this:
class PersonBuilder {
private var age: Int? = null
private var name: String? = null
fun setAge(age: Int) = apply { this.age = age }
fun setName(name: String) = apply { this.name = name }
fun build() = Person(age!!, name!!) //be careful!
}
Anyway, be careful with the build function. There are no guarantees that the functions setAge and setName will be called before it, so you can get a NullPointerException
Update
Another way to solve this problem by keeping @JvmSynthetic
is to add the @JvmField
notation as well. See this article for more information.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论