Почему JsonNull в GSON?
Документы говорят, что метод JsonObject # get возвращает значение null, если такой член не существует. Это неточно; иногда вместо null
возвращается объект JsonNull
.
Какова идиома для проверки того, существует ли конкретное поле в GSON? Я хочу избежать этого неуклюжего стиля:
jsonElement = jsonObject.get("optional_field");
if (jsonElement != null && !jsonElement.isJsonNull()) {
s = jsonElement .getAsString();
}
Почему GSON использовал JsonNull
вместо null
?
Существует ответ , что - различия между null
и JsonNull
. В моем вопросе выше я ищу причины, по которым.
Ответы
Ответ 1
Гссон, по-видимому, хотел смоделировать разницу между отсутствием значения и наличием значения JSON null
в JSON. Например, существует разница между этими двумя фрагментами JSON
{}
{"key":null}
ваше приложение может считать их одинаковыми, но формат JSON не поддерживает.
Вызов
JsonObject jsonObject = new JsonObject(); // {}
jsonObject.get("key");
возвращает значение Java null
, поскольку ни один член не существует с этим именем.
Вызов
JsonObject jsonObject = new JsonObject();
jsonObject.add("key", JsonNull.INSTANCE /* or even null */); // {"key":null}
jsonObject.get("key");
возвращает экземпляр типа JsonNull
(singleton, на который ссылается JsonNull.INSTANCE
), потому что член существует с этим именем, и его значение равно JSON null, представленное значением JsonNull
.
Ответ 2
Я знаю, что вопрос не требует решения, но я пришел сюда в поисках одного. Поэтому я опубликую это на тот случай, если это кому-то понадобится.
Ниже код расширения Kotlin избавляет от необходимости проверять null
и isJsonNull
отдельно для каждого элемента.
import com.google.gson.JsonElement
import com.google.gson.JsonObject
fun JsonObject.getNullable(key: String): JsonElement? {
val value: JsonElement = this.get(key) ?: return null
if (value.isJsonNull) {
return null
}
return value
}
и вместо того, чтобы звонить, как это
jsonObject.get("name")
ты так называешь
jsonObject.getNullable("name")
Работы особенно создают во вложенных структурах. Ваш код в конечном итоге будет выглядеть так
val name = jsonObject.getNullable("owner")?.asJsonObject?.
getNullable("personDetails")?.asJsonObject?.
getNullable("name")
?: ""