java - 为什么我在使用 Gson.asString 时收到 java.lang.UnsupportedOperationException?

标签 java android json kotlin gson

代码基于以下链接: Link

我遇到运行时异常:

java.lang.UnsupportedOperationException: JsonObject 运行以下代码时:

data class Student(
    var name: String? = null,
    var address: String? = null) {
}

    class StudentDeserializer : JsonDeserializer<Student> {
    
        override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Student {
            json as JsonObject
    
            val name = json.asString
            val addressJson = json.get("address")
            val address = if (addressJson.isJsonObject) addressJson.toString() else addressJson.asString
            return Student(name, address)
        }
    }

错误在于:

    val name = json.asString

这是反序列化方法的一部分,在我编写时可能会调用该方法:

        val student = gSon.fromJson<Student>(json2, Student::class.java)

当站在这条线上方并按 ctrl + b 键盘时,它会将我带到 JsonElement 类,并看到以下方法:

public String getAsString() {
  throw new UnsupportedOperationException(getClass().getSimpleName());
}

我们可以看到,这里只有一个 throw 语句。但是如果我们阅读方法文档,我们会发现那里写着 throw 语句发生只是方法的一部分。

/**
* convenience method to get this element as a string value.
*
* @return get this element as a string value.
* @throws ClassCastException if the element is of not a {@link JsonPrimitive} and is not a valid
* string value.
* @throws IllegalStateException if the element is of the type {@link JsonArray} but contains
* more than a single element.
*/
public String getAsString() {
   ...

我的问题是:

  1. 完整的实现在哪里?
  2. 为什么当我在如下代码中单击 ctrl + b 时: someJsonObject.asString ,我猜它是一个属性,它需要我使用名称的方法: getAsString 这是否意味着 asString 属性的 get() 实现是:return getAsString(this)?

最佳答案

JsonElement::getAsString() 仅适用于 json 基元。原语是字符串、数字和 boolean 值。您的 json 实例是一个 JsonObject,因此不是一个基元,这意味着没有实现返回有意义的值的 getAsString()

根据教程,您实际上应该执行 json.get("name").asString

json.get("name") 将返回 name 元素,该元素的类型为 JsonPrimitive -> 一个 json 基元,您可以在其中使用可以调用getAsString()

为了进一步说明,这是 json 的内容:

{
   "name": "Mark",
   "address": {
        "city": "London",
        "post": "12000"
    }
 }

这是json.get("name")的内容:

"Mark"

当调用 getAsString()/asString 时,它将生成字符串 Mark


另请参阅:GSON JsonElement.getAsString vs. JsonElement.toString?


关于源代码的问题。 JsonPrimitiveJsonObject 的子类。当您导航时,IDE 只知道它必须是一个 JsonObject,但在运行时,它会发现它实际上是一个基元并调用 JsonPrimitive::getAsString()。其来源在这里:https://github.com/google/gson/blob/master/gson/src/main/java/com/google/gson/JsonPrimitive.java#L137-L151

这是 gson 利用继承的结果。如果您需要进一步帮助来理解这一点,我建议您阅读一些有关 Java 面向对象编程的初学者 Material 。

关于java - 为什么我在使用 Gson.asString 时收到 java.lang.UnsupportedOperationException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64665464/

相关文章:

javascript - 正则表达式匹配不带引号的字符串,但不匹配 CSV 中的数字

javascript - Node-red 崩溃/JSON 输出有时会返回 html

java - 单击时 ListView 选择多个项目

JavaFX 导出到 jar。未找到主类

android - 错误 :Cannot configure the 'publishing' extension after it has been accessed

android - ImageButton OnClickListener 未触发

android - 如何在android gradle项目中包含lvl-license项目

java - 将矩阵和 double 组解析为 la4j 对象

java - 浏览多个列表以查找相等的对象

javascript - Gatsby JSON 中的绝对图像路径