【问题标题】:Ambiguous method call with JvmSynthetic setter使用 JvmSynthetic setter 进行模糊方法调用
【发布时间】:2020-08-06 12:39:33
【问题描述】:

我有一个带有 @JvmSynthetic 设置器的类,以便为 Java 客户端仅提供流畅的类似构建器的设置器:

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!!)
}

在 Java 端这样称呼它:

new PersonBuilder()
        .setAge(22)  // <- "error"
        .setName("Peter")
        .build();

它确实编译并运行,但 Android Studio 显示错误“不明确的方法调用。PersonBuilder 中的 setAge (Integer) 和 PersonBuilder 中的 setAge (Integer) 都匹配”并且不提供任何自动- 此“错误”之后的建议和代码格式。

【问题讨论】:

    标签: java android-studio kotlin


    【解决方案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!!) //be careful!
    }
    

    无论如何,请小心构建功能。不能保证函数 setAge 和 setName 会在它之前被调用,所以你可以获得 NullPointerException

    更新

    通过保留@JvmSynthetic 来解决此问题的另一种方法是添加@JvmField 符号。请参阅this article 了解更多信息。

    【讨论】:

    • 我需要 @set:JvmSynthetic 在 Kotlin 端使用这些设置器
    • this article。第 3 节说:“请注意,如果我们有一个使用 *@JvmSynthetic* 注释但未使用 *@JvmField* 注释的 Kotlin 字段,则生成的 getter 和 setter 不被视为合成方法,可以正常访问我>“
    • @JvmField 解决了这个问题。 @bruno-azevedo 能否请您写下完整的答案,以便我将问题标记为已解决?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多