【问题标题】:Kotlin call Java platform types result in llegalStateExceptionKotlin 调用 Java 平台类型导致非法状态异常
【发布时间】:2017-07-16 10:00:22
【问题描述】:

我在我的一个 Android 类中使用 kotlin,当尝试从 Bundle 获取额外信息时,似乎有时会在这一行弹出一个 IllegalStateException

keyOrTag = bundle.getString("tag")

val 是这样声明的

val keyOrTag: String

很遗憾,我没有完整的堆栈跟踪,因为我从 GP 控制台中注意到了这一点。

【问题讨论】:

    标签: android exception kotlin stack-trace


    【解决方案1】:

    好的,我相信我知道为什么会发生这种情况。将其作为答案发布,以便其他有相关问题的人可以看到。

    添加到捆绑包中的String "tag" 实际上可以是Java 类中的null,该Java 类将其发送到Kotlin 之一。而且由于我没有将 val 声明为可为空,我相信这就是它抛出 IllegalStateException 的原因(是的,在 kotlin 中没有 NPE)。

    修复:

    val keyOrTag: String?
    

    【讨论】:

    • 其实不应该是var keyOrTag: String? = null吗? val 是最终变量,因此只能通过构造函数或就地初始化。
    • @k0sh 如果我用null 初始化它,我将无法从Bundle 中给它值。我只需要那个变量有一个值。这种方法不正确吗?
    • 这实际上是Kotlin 问题,应该在编译时而不是运行时显示错误,因为bundle.getString() 方法可能会返回null,希望Kotlin 的所有者尽快修复此问题
    • @AlexNewman val 变量应该通过构造函数或在线初始化,看看val simple: Int? // has type Int, default getter, must be initialized in constructorkotlinlang.org/docs/reference/properties.html 我不确定上面的内容如何不会出现错误,除非你通过捆绑到构造函数然后它应该没问题,但我不确定,因为我看不到你的代码。
    • @k0sh 哦,很抱歉没有提供足够的上下文。我在函数内声明该变量,而不是全局声明。并在同一个函数中初始化它。
    【解决方案2】:

    何时出现此错误?

    IllegalStateException 可能是在您调用 Java 平台类型时由 Kotlin kotlin.jvm.internal.Intrinsics 抛出的。

    为什么您看不到来自 Kotlin 的 Exception throws by kotlin.jvm.internal.Intrinsics 的 stackTrace?

    这是因为 stackTrace 在内部被 Kotlin 在 Intrinsics#sanitizeStackTrace 方法中删除:

    private static <T extends Throwable> T sanitizeStackTrace(T throwable) {
        return sanitizeStackTrace(throwable, Intrinsics.class.getName());
    }
    

    示例

    这里是一个Java平台类型StringUtils源代码,如果value参数为null""toNull方法将返回null

    public class StringUtils {
        public static String toNull(String value) {
            return value == null || value.isEmpty() ? null : value;
        }
    }
    

    然后您尝试将方法调用的结果分配给一个不可为空的变量可能会抛出IllegalStateException,例如:

    val value: String = StringUtils.toNull("")
    //         ^
    //throws IllegalStateException: StringUtils.toNull("") must not be null
    //try to assign a `null` from `toNull("")` to the non-nullable variable `value`
    

    如何避免kotlin.jvm.internal.Intrinsics 抛出此类异常?

    如果你不确定返回值是否来自Java平台类型null,你应该将值赋给一个nullable 变量/使返回类型可为空,例如:

    val value: String? = StringUtils.toNull("")
    //         ^--- it works fine   
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多