Kotlin: Platform declaration clash: The following declarations have the same JVM signature (test(Lkotlin/jvm/functions/Function0;)V):
fun <P1, R> test(init: () -> (P1) -> R): Unit defined in com.example.springsandbox
fun <P1, P2, R> test(init: () -> (P1, P2) -> R): Unit defined in com.example.springsandbox
public final class NotepadKt {
@JvmName(
name = "test1"
)
public static final void test1(@NotNull Function0 init) {
Intrinsics.checkNotNullParameter(init, "init");
}
@JvmName(
name = "test2"
)
public static final void test2(@NotNull Function0 init) {
Intrinsics.checkNotNullParameter(init, "init");
}
public static final void main() {
test1((Function0)null.INSTANCE);
Unit test1 = Unit.INSTANCE;
test2((Function0)null.INSTANCE);
Unit test2 = Unit.INSTANCE;
}
// $FF: synthetic method
public static void main(String[] var0) {
main();
}
}
1条答案
按热度按时间wfsdck301#
这是因为JVM。¯_()_/¯
让我们先看看这个例子:
代码会编译吗?令人惊讶的是,即使声明了类型,编译也会失败,并显示消息:
这条消息告诉我们很多可能存在问题的地方。我们可以通过更改JVM签名轻松修复它:
现在,我们的代码可以编译了,但是我们仍然需要在调用
test
函数时添加类型。所以让我们检查一下下面发生了什么。字节码中的Test-fun访问器如下所示:
两个测试函数具有(几乎)相同的签名:
Function0
(唯一的区别是函数名,已经被@JvmName
annotation改变了)。泛型类型不在这里,因为JVM已经删除了它;)我们也可以反编译工作代码来查看冲突:
这清楚地告诉我们哪里有问题-两个声明的函数都采用相同的参数,所以我们需要帮助Kotlin编译器选择哪一个。
参考:https://docs.oracle.com/javase/tutorial/java/generics/erasure.html
所以,我不确定这是否可以被认为是一个bug,或者更像是JVM的限制(或者,事实上,如果我们考虑类型继承(我指的是
T: () -> Any, S: () -> () -> Any; S is a subtype of T
),答案可能不是那么明显)。