3

可能只是我用错了,因为我是 Kotlin 和 Moshi 的新手。

data class InitialAppResult(val status: Int, val message: String, val baseprm: String)

val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()  
val adapter = moshi.adapter(InitialAppResult::class.java)
val fromJson = adapter.fromJson(result.get())

fromJson 怎么可能是空的并且需要一个 !! 或者 ?。例如:fromJson!!.baseprm

如果解析失败并且缺少必填字段,则在我的情况下它只会引发异常。那么它如何解析“无效”的 JSON 响应而不失败,即返回 null 呢?

4

1 回答 1

2

Moshi 是一个用 Java 实现的库,而您的代码是用 Kotlin 编写的。引用文档中的“从 Kotlin 调用 Java 代码”部分:

Java 中的任何引用都可能为空,这使得 Kotlin 对来自 Java 的对象的严格空安全性要求不切实际。

这意味着任何来自 Java 的对象在默认情况下都可以为空。但是,如果您将变量声明为不可为空的类型,Kotlin 将自动“转换”它:

当一个平台值[即本例中的 Java 对象]被分配给 Kotlin 变量时,我们可以依赖类型推断(该变量将具有推断的平台类型,如上例中的 item ),或者我们可以选择我们期望的类型(允许为空和非空类型)。

这是一个示例(同样来自上面链接的文档),其中item是 Java 对象:

val nullable: String? = item // allowed, always works
val notNull: String = item // allowed, may fail at runtime

因此,在您的情况下,您可以通过键入以下内容强制对象不可为空:

val fromJson: InitialAppResult = adapter.fromJson(result.get())

编辑

在这种情况下,所有fromJson方法都定义为@Nullable(作为null有效的 JSON 值),这意味着结果可以是null,因此推断的类型可以为空。这同样适用于@NotNull。所以这些注解在 Java 和 Kotlin 之间的互操作性的情况下非常有用。

在其他情况下,如果缺少@Nullableor@NotNull注释,上述关于显式将值添加到变量的内容是正确的。

编辑 21/07/2020

为什么fromJson标记为@Nullable

原因是这null是一个有效的 JSON 值。以下示例都是有效的 JSON 字符串:

  • null
  • { "key": null }

因此,JsonAdapter需要能够处理null值。例如,这是内置ObjectJsonAdapter处理nulls 的方式:

@Override public Object fromJson(JsonReader reader) throws IOException {
    ...
    case NULL:
      return reader.nextNull();
}

这依赖于nextNull,其文档说:

使用 JSON 流中的下一个标记并断言它是一个文字空值。返回空值。

于 2018-03-04T09:54:55.040 回答