Kotlin声明签名冲突?

时间:2019-06-18 10:23:55

标签: generics kotlin constructor jvm bytecode

我知道这已经被问过了,但是给出的解决方案在这里不适用。

有问题的代码是一个简单的类:

class BitString(bits: List<Bit>) {
    constructor(bits: List<Number>): this(bits.map(::Bit))
    constructor(bits: List<Boolean>): this(bits.map(::Bit))

    var bits = bits

}

Bit是我实现的一类。

但是我很熟悉:

Platform declaration clash: The following declarations have the same JVM signature (<init>(Ljava/util/List;)V):
    constructor BitString(bits: List<Bit>) defined in BitString
    constructor BitString(bits: List<Boolean>) defined in BitString
    constructor BitString(bits: List<Number>) defined in BitString

我的猜测是,生成的字节码无法在不同的专用列表之间进行区分,这似乎应该优先解决,但显然不是。

我的问题是我应该如何使此代码正常工作,并且看起来更好?关键是应该使用ListBitNumber中的Boolean,以便可以从广泛的集合中构造类。

1 个答案:

答案 0 :(得分:1)

如果要保留构造函数的外观,可以将companion objectinvoke-operator结合使用:

class BitString(val bits: List<Bit>) {
  companion object {
    @JvmName("fromNumbers")
    operator fun invoke(bits : List<Number>) = BitString(bits.map(::Bit))
    @JvmName("fromBooleans")
    operator fun invoke(bits : List<Boolean>) = BitString(bits.map(::Bit))
  }
}

然后构造BitString就像调用构造函数一样

BitString(yourNumberList) // calls fromNumbers
BitString(listOf(true, false)) // calls fromBooleans
BitString(listOf(Bit(...))) // the actual constructor