Earlier versions of Moshi didn't support "codegen", so they completely relied on reflection (i.e., the ability to introspect classes at runtime). However, that could be a problem for applications that require very high performance so they've added a "codegen" capability that takes advantage of annotation processing. Basically that allows generating code at compilation time, so they can perform serialisation/deserialisation without using reflection.
为了启用代码生成功能,您还需要启用Kapt,它是Kotlin注释处理器,否则不会进行注释处理.
Here you'll find how to enable and configure Kapt, and here you'll find how to set up Moshi codegen dependencies.
编辑
在您添加到问题中的代码片段中,Moshi使用ClassJsonAdapter来序列化您的对象.该适配器利用反射查找所有字段并创建JSON字符串(您可以看到该类从java.lang.reflect
导入内容).
另一方面,Moshi为你的班级编写了generates a 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()
}
}
As a result, when you ask for an adapter for Person
, Moshi will use the generated PersonJsonAdapter
instead of the ClassJsonAdapter
.
prize
Moshi uses reflection to instantiate the generated adapter (which then gets cached, so that it gets reused next time you ask for an adapter for the same class), so that you don't need to add any extra code at all if you want to use the codegen functionality.