【发布时间】:2017-11-14 13:58:02
【问题描述】:
我的代码按预期工作,但我很好奇为什么会出现以下警告:
忽略警告是否安全? 我知道 Kotlin 无法在运行时检查擦除的类型,但它不是 Kotlin 中最通用的(顶级)对象。
我正在寻找的是一种检查对象是否属于“lambda”类型的方法。 顺便说一句:有吗? -> 有吗?也没有解决问题。
【问题讨论】:
我的代码按预期工作,但我很好奇为什么会出现以下警告:
忽略警告是否安全? 我知道 Kotlin 无法在运行时检查擦除的类型,但它不是 Kotlin 中最通用的(顶级)对象。
我正在寻找的是一种检查对象是否属于“lambda”类型的方法。 顺便说一句:有吗? -> 有吗?也没有解决问题。
【问题讨论】:
JVM 仅在运行时为您提供原始类型,例如java.lang.List 而不是 java.lang.List<String>。这也适用于 kotlin lambda:当您在 kotlin 中编写 (Any?) -> Unit 时,它会被转换为 JVM 类型 kotlin.jvm.functions.Function1<java.lang.Object, kotlin.Unit>。
现在,您有一个Any? 类型的对象。你可以写Any? as? Function1<*, *> 没有任何问题。您也可以使用as 代替as?,但有ClassCastException 被抛出的风险。
但现在问题来了:(Any?) -> Unit 和 (Int) -> String 类型在编译时是不同的类型,但这只是因为它们的泛型类型参数。在运行时,两者都是Function1 的实例,这就是为什么当您将其转换为具有* 以外的通用参数的任何东西时编译器会发出警告。
忽略警告是否安全?
如果您知道自己在做什么 - 是的,这只是 Java 语言的限制。如果您可以依赖于您所期望的类型,则不会出现错误,但是如果泛型参数与您期望的不同,您将不会收到任何异常。
如果您不知道自己在做什么,例如从您无法控制的代码中获取参数 - 请认真对待此警告。
【讨论】: