GSON框架中JsonElement与JsonObject实例关联及嵌套对象entrySet疑问
members变量相关问题解答 咱们先拆解你的第一个问题:
问题1:JsonObject的members变量由谁、在何处填充?
当你调用jsonParser.parse(bufferRead)时,GSON的内部解析器会逐行处理传入的JSON字符串。一旦解析到{}包裹的JSON对象结构,GSON会立刻创建一个JsonObject实例,接着逐个解析这个对象里的键值对,通过JsonObject.add(String name, JsonElement value)方法,把每一组键值对存入members这个LinkedTreeMap中。
简单总结:
- 谁来填充:GSON内置的解析逻辑(具体是
JsonReader配合解析器的处理流程)负责完成填充。 - 在哪里填充:在
jsonParser.parse()方法执行过程中,解析到JSON对象结构的瞬间,就会动态创建JsonObject并同步填充members。
你调用的getAsJsonObject()只是把parse()返回的JsonElement父类实例,安全强转为JsonObject子类实例——这时候members早就被解析过程填充完成了,和getAsJsonObject()的调用没有关系。
问题2:为什么获取"address"对应的JsonObject能调用entrySet()?
先理清楚这段代码的执行逻辑:jsonParser.parse(bufferRead).getAsJsonObject().getAsJsonObject("address")
- 先解析整个JSON字符串,得到根节点的
JsonObject - 从根对象中取出键为
"address"的JsonElement,再强转为JsonObject
而这个address对应的JsonObject,在解析整个JSON的过程中已经被GSON完整构建好了——它内部的members变量已经存好了自身的键值对。JsonObject类本身就实现了entrySet()方法,这个方法的内部逻辑就是直接返回members.entrySet(),所以只要你拿到的是一个有效的、已经被解析填充过的JsonObject实例,自然就能调用entrySet()获取它的键值对集合。
你之前遍历根对象时看到address是JsonObject类型,就说明这个字段本身就是一个JSON对象结构,GSON已经为它创建了对应的JsonObject实例并填充了内部的members,所以后续直接获取它之后调用entrySet()完全合理。
内容的提问来源于stack exchange,提问作者Shannin

