我正在尝试创建以下类:
class MyClass {
var foos: List<Foo> = listOf()
constructor(foos: List<Foo>) {
this.foos = foos
}
constructor(bars: List<Bar>) : super() {
this.foos = bars.map { bar ->
Foo(bar)
}
}
}
但是,我收到一条错误消息:
Platform declaration clash: The following declarations have the same JVM signature ( (Ljava/util/List;)V):
我知道它们都是 List 对象,但它们是用泛型类型化的,所以我确信这不会有问题。
最佳答案
你遇到这个问题是因为在 java 中存在一个叫做 type erasure 的东西。 .并且因为 kotlin 使用 JVM,它也受到此限制的影响。给一个 TL;DR;
通用类型保留在 .class
中文件,以便 java 知道该类(在您的情况下为 List
)是通用的。但它无法跟踪实例的通用类型。所以实例List<Foo>
和 List<Bar>
都在他们的 raw type 中处理运行时的形式(List
)。请记住,泛型仅在编译时使用以确保类型安全。
要克服此限制,您可以在 kotlin 中使用运算符重载。我们正在查看的运算符是 ()
让你调用任何实例。通过使用 companion object
我们甚至可以做到这一点
invoke
看起来像一个构造函数,并且像一个构造函数一样被调用(MyClass()
)。您的代码可能如下所示:
class MyClass(var foos: List<Foo>) {
companion object {
operator fun invoke(bars: List<Bar>) = MyClass(bars.map(::Foo))
}
}
它允许您像这样简单地调用它:
val mc1 = MyClass(foos) // calls constructor
val mc2 = MyClass(bars) // calls companion.invoke
关于java - Kotlin - 无法创建两个具有不同列表类型参数的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56384970/