为什么在使用 fromJson 解析 json 时,Moshi return 是一个可为空的对象?

Why does Moshi return a nullable object when parsing json with fromJson?

可能只是我用错了,因为我是 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 可以为 null 并且需要一个 !!要么 ?。例如:fromJson!!.baseprm

如果解析失败并缺少必填字段,在我的情况下它只会抛出异常。那么它如何解析 "invalid" JSON 响应而不失败,即 return null?

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

Any reference in Java may be null, which makes Kotlin's requirements of strict null-safety impractical for objects coming from Java.

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

When a platform value [i.e., a Java object in this case] is assigned to a Kotlin variable, we can rely on type inference (the variable will have an inferred platform type then, as item has in the example above), or we can choose the type that we expect (both nullable and non-null types are allowed).

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

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

因此,在您的情况下,您可以通过键入以下内容强制对象成为 non-nullable:

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

编辑

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

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

编辑 2020 年 7 月 21 日

Why does fromJson is marked as @Nullable?

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

  • null
  • { "key": null }

因此,JsonAdapter 需要能够处理 null 值。例如,下面是 built-in ObjectJsonAdapter 处理 null 的方式:

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

那依赖于 nextNull,其 documentation 说:

Consumes the next token from the JSON stream and asserts that it is a literal null. Returns null.