Leo*_*ela 5 java generics jvm kotlin
我试图创建以下类:
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)
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到一条错误消息:
平台声明冲突:以下声明具有相同的 JVM 签名( (Ljava/util/List;)V):
我知道它们都是 List 对象,但它们是用泛型键入的,所以我确信这不会有问题。
您会遇到这个问题,因为在 Java 中存在称为类型擦除的东西。并且因为 kotlin 使用 JVM,所以它也受此限制的影响。给 TL;DR;
泛型类型保留在.class文件中,因此 java 知道该类(在您的情况下List)是泛型的。但它无法跟踪实例的泛型类型。因此,实例List<Foo>和List<Bar>都在运行时以其原始类型形式处理(List )。请记住,泛型仅在编译时使用以确保类型安全。
为了克服这个限制,您可以在 kotlin 中使用运算符重载。我们正在研究的运算符是()让您调用任何实例的运算符。通过使用 acompanion object我们甚至可以使它
invoke看起来像一个构造函数,并像一个 ( MyClass())一样被调用。您的代码可能如下所示:
class MyClass(var foos: List<Foo>) {
companion object {
operator fun invoke(bars: List<Bar>) = MyClass(bars.map(::Foo))
}
}
Run Code Online (Sandbox Code Playgroud)
这允许您像这样简单地调用它:
val mc1 = MyClass(foos) // calls constructor
val mc2 = MyClass(bars) // calls companion.invoke
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
686 次 |
| 最近记录: |