【问题标题】:Interoperability java-kotlin Nullable string crashing at runtime but why?互操作性 java-kotlin Nullable 字符串在运行时崩溃,但为什么?
【发布时间】:2022-09-24 01:49:52
【问题描述】:

我有一个替代我的问题,但我仍然有 2 个问题:

  • 为什么会崩溃
  • 为什么 Intellij/编译器不抱怨

我提供了我的问题的一个小例子。这是一个概述(您可以在后面找到代码)

  • 汽车.java是带有一个简单 getter 的 java 类,注释为可以为空
  • 我的视图.kt是在 Intellij 或 gradle 中没有警告的运行时崩溃示例。 (当值为空时崩溃)
  • MyView2.kt不是在运行时崩溃(即使 mType 为空)
  • Library.kt (kotlin 标准库)只是示例的预期调用(即使看到string.toString() 很奇怪)

汽车.java

    @Nullable
    private String mType;

    @Nullable
    public String getCarType() {
        return mType;
    }

我的视图.kt(崩溃)

    val test: String = myCar.carType.toString()

MyView2.kt(不崩溃)

    val carType: String? = myCar.carType
    val test2: String = carType.toString()

图书馆.kt(科特林标准库)

    /**
     * Returns a string representation of the object. Can be called with a null receiver, in which case
     * it returns the string \"null\".
     */
    public fun Any?.toString(): String

谢谢!我想这是 kotlin 和 java 之间互操作的一个极端案例?或者......有人知道更好的解释吗?

  • 你能显示堆栈跟踪吗?您正在使用哪些可空性注释?你能在 Car.java 文件的顶部显示你正在使用的导入吗?我的第一个猜测是您正在使用 Kotlin 的编译器无法识别的可空性注释。

标签: kotlin


【解决方案1】:

这种差异的线索是 MyView2.kt 中这一行中的可选标记 ?

val carType: String? = myCar.carType

- 在这里,您向 Kotlin 编译器声明您知道 carType 可以为空。 (反过来,.toString() 的行为即使在 null 对象上调用也会起作用,正如您从文档中显示的那样。)

然而,MyView.kt 中的情况有所不同,因为代码没有达到.toString() 调用的程度。在这里,您直接使用平台类型(即Java)不能推导出空安全规则。

这份关于Calling Java code from Kotlin 的文档解释说:

Java 声明的类型在 Kotlin 中以特定方式处理,称为平台类型。此类类型的空值检查被放宽,因此对它们的安全保证与 Java 中的相同

【讨论】:

    猜你喜欢
    • 2014-07-25
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多