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

Why am I getting the java.lang.UnsupportedOperationException when using Gson.asString?

代码基于以下link: 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

这是 deserialize 方法的一部分,我写的时候可能会调用它:

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

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

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

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

/**
* 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()实现是:returngetAsString(this)?

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

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

json.get("name") 将 return 属于 JsonPrimitive 类型的 name 元素 -> 可以调用 [=15= 的 json 原语].

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

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

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

"Mark"

当调用 getAsString() / asString 时,结果将是字符串 Mark


另见:


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

这是gson利用继承的结果。如果您需要进一步的帮助来理解这一点,我建议阅读一些初学者 material 中的 object-oriented programming for Java。