我最近开始在我的Android应用程序中使用Moshi,但我很想知道有关@JsonClass(generateAdapter = true)
注释实际功能的更多信息。
数据类示例:
data class Person(
val name: String
)
我可以按如下方式序列化/反序列化此类:
val moshi: Moshi = Moshi.Builder().build()
moshi.adapter(Person::class.java).toJson(Person())
我是而不是,在这里使用@JsonClass批注,因此代码生成将无法启动。
我的问题是,为什么和何时需要使用
@JsonClass(generateAdapter = true)
最佳答案
Moshi的早期版本不支持“codegen”,因此它们完全依赖于反射(即在运行时自省(introspection)类的能力)。但是,这对于需要非常高性能的应用程序可能是个问题,因此他们添加了利用注释处理的“codegen”功能。基本上,这允许在编译时生成代码,因此它们可以在不使用反射的情况下执行序列化/反序列化。
为了启用代码生成功能,您还需要启用Kapt,它是Kotlin注释处理器,否则将不会进行任何注释处理。
Here您将找到如何启用和配置Kapt,而here您将找到如何设置Moshi codegen依赖项。
编辑
在您添加到问题的代码片段中,Moshi使用ClassJsonAdapter序列化您的对象。该适配器利用反射来查找所有字段并创建JSON字符串(您可以看到该类从java.lang.reflect
导入东西)。
另一方面,Moshi代码生成会为您的类生成一个JsonAdapter。例如,让Moshi为您的Person
类创建适配器将生成以下内容:
// Code generated by moshi-kotlin-codegen. Do not edit.
import com.squareup.moshi.JsonAdapter
import com.squareup.moshi.JsonDataException
import com.squareup.moshi.JsonReader
import com.squareup.moshi.JsonWriter
import com.squareup.moshi.Moshi
import java.lang.NullPointerException
import kotlin.String
class PersonJsonAdapter(moshi: Moshi) : JsonAdapter<Person>() {
private val options: JsonReader.Options = JsonReader.Options.of("name")
private val stringAdapter: JsonAdapter<String> =
moshi.adapter<String>(String::class.java, kotlin.collections.emptySet(), "name")
override fun toString(): String = "GeneratedJsonAdapter(Person)"
override fun fromJson(reader: JsonReader): Person {
var name: String? = null
reader.beginObject()
while (reader.hasNext()) {
when (reader.selectName(options)) {
0 -> name = stringAdapter.fromJson(reader) ?: throw JsonDataException("Non-null value 'name' was null at ${reader.path}")
-1 -> {
// Unknown name, skip it.
reader.skipName()
reader.skipValue()
}
}
}
reader.endObject()
var result = Person(
name = name ?: throw JsonDataException("Required property 'name' missing at ${reader.path}"))
return result
}
override fun toJson(writer: JsonWriter, value: Person?) {
if (value == null) {
throw NullPointerException("value was null! Wrap in .nullSafe() to write nullable values.")
}
writer.beginObject()
writer.name("name")
stringAdapter.toJson(writer, value.name)
writer.endObject()
}
}
结果,当您要求
Person
的适配器时,Moshi将使用生成的PersonJsonAdapter
而不是ClassJsonAdapter
。奖金
Moshi uses reflection to instantiate the generated adapter(然后将其缓存,以便下次您请求同一类的适配器时可以重新使用),因此,如果您想使用codegen功能,则根本不需要添加任何额外的代码。
关于json - Moshi的Kotlin码本有什么用?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58501918/