【问题标题】:Unchecked cast when casting an object of type Any? into a lambda in kotlin投射任何类型的对象时未经检查的投射?在 kotlin 中变成 lambda
【发布时间】:2017-11-14 13:58:02
【问题描述】:

我的代码按预期工作,但我很好奇为什么会出现以下警告:

忽略警告是否安全? 我知道 Kotlin 无法在运行时检查擦除的类型,但它不是 Kotlin 中最通用的(顶级)对象。

我正在寻找的是一种检查对象是否属于“lambda”类型的方法。 顺便说一句:有吗? -> 有吗?也没有解决问题。

【问题讨论】:

    标签: lambda kotlin


    【解决方案1】:

    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 语言的限制。如果您可以依赖于您所期望的类型,则不会出现错误,但是如果泛型参数与您期望的不同,您将不会收到任何异常。

    如果您不知道自己在做什么,例如从您无法控制的代码中获取参数 - 请认真对待此警告。

    【讨论】:

    • 感谢您提供如此清晰的解释。我控制代码,我希望 fixAUd 始终是 lambda 表达式(或者,在最坏的情况下为 null)
    • @feresr 但是如果它总是一个 lambda 或 null,那你为什么需要演员表呢?
    • 为了能够调用它,我正在实现一个接口并且参数 fixAUd 的类型是 Any?,无法更改。我所能做的就是确保始终将 lambda 作为参数传递。
    猜你喜欢
    • 1970-01-01
    • 2023-01-20
    • 1970-01-01
    • 2023-02-03
    • 1970-01-01
    • 2012-06-09
    • 1970-01-01
    • 2012-02-13
    • 2017-03-17
    相关资源
    最近更新 更多