我试图在下面的代码片段中了解父级和子级实例的作用域或它们的行为。 (通过GSON框架了解下位功能)
private static JsonObject jsonObjectAddress = new JsonObject();
jsonObjectAddress = jsonParser.parse(bufferRead).getAsJsonObject().getAsJsonObject("address");
Set<Entry<String, JsonElement>> entrySetProperties = jsonObjectAddress.entrySet();
想要了解:
jsonParser.parse(bufferRead)
返回JsonElement
类实例,它是JsonObject
类的父类。
并且JsonObject
类在其内部具有Instnce变量,并且由所有具有键值对的JSON属性组成。
private final LinkedTreeMap<String, JsonElement> members =
new LinkedTreeMap<String, JsonElement>();
只是好奇地知道,members
的填充位置和填充者是因为它作为实例变量出现在子类中,而jsonParser.parse(bufferRead)
仅返回JsonElement实例...!
我可以知道它的工作原理吗?我们将不胜感激,以了解更多......
更新:
运行此
jsonObjectAddress = jsonParser.parse(bufferRead).getAsJsonObject();
Set<Entry<String, JsonElement>> entrySetProperties = jsonObjectAddress.entrySet();
for(Map.Entry<String, JsonElement> entry: entrySetProperties) {
System.out.println(entry.getValue().getClass());
System.out.println(entry.getKey()+":"+ entry.getValue());
}
它给了我以下结果
class com.google.gson.JsonPrimitive
empID:100
class com.google.gson.JsonPrimitive
name:"David"
class com.google.gson.JsonPrimitive
permanent:false
class com.google.gson.JsonObject
address:{"street":"BTM 1st Stage","city":"Bangalore","zipcode":560100}
class com.google.gson.JsonArray
phoneNumbers:[123456,987654]
class com.google.gson.JsonPrimitive
role:"Manager"
class com.google.gson.JsonArray
cities:["Los Angeles","New York"]
class com.google.gson.JsonObject
properties:{"age":"28 years","salary":"1000 Rs"}
上面的结果是member
类的JsonObject
实例变量的值。但是,如果您看到member
中的值之一就是JsonObject本身。
所以,如果我这样跑
jsonObjectAddress = jsonParser.parse(bufferRead).getAsJsonObject().getAsJsonObject("address");
它表示类型JsonObject
的相同值,该值存储在addreess
中的键名member
中,并显示类似这样的结果
class com.google.gson.JsonPrimitive
street:"BTM 1st Stage"
class com.google.gson.JsonPrimitive
city:"Bangalore"
class com.google.gson.JsonPrimitive
zipcode:560100
在这里感到困惑,address
中的member
键具有JsonObject
,所以当我们仅提取address`时,它如何返回entryset()...?
答案 0 :(得分:1)
解析器通过解析JSON字符串创建一棵JsonElements树,其返回值是作为该树根的元素。解析器是谁负责填充成员集的答案。这就是解析器解析输入的内容。
没有要做的“保持联系”;有一个等效于JSON的数据结构。例如,如果您的JSON是
{ "stuff" : { "foo" : "F" , "bar" : "B" } }
然后,顶级JsonObject中的映射有一个条目,键为“ stuff”,该条目的值为一个JsonObject,其映射中有两个条目,键为“ foo”和“ bar”,其值为JsonPrimitive值,在这种情况下为字符串。
随后的“获取”操作从该树中检索节点。
当你写这篇文章时:
private static JsonObject jsonObjectAddress = new JsonObject();
您分配了一个从未使用过的新JsonObject,因为在下一行
jsonObjectAddress = ...
您将变量设置为另一个JsonObject,该JsonObject存在于解析器创建的树结构中。
编辑更多:
也许我误解了您对父母/子女术语的使用。我将其解释为引用对象树中的父/子关系。但似乎您也提到了超类/子类关系。
我认为您看错了方式。没有单独的“ JsonObject实例”和“ JsonElement实例”。 (至少在概念上)只有一个物体。该对象是JsonElement,并且(在这种情况下)它也是JsonObject。
这就是Java类的工作方式。
因此,当您从解析树中获取节点时,会将其视为JsonElement,因为这是所有可能性的基本类型。元素可以是JsonObject,JsonPrimitive,JsonArray或JsonNull。当您调用“ getAsJsonObject”时,您基本上是在说您现在想将拥有的元素视为对象(并且GSON内部会检查这样做是否有意义)。
在更新问题后添加。
jsonObjectAddress =
jsonParser.parse(bufferRead) // builds tree, returns
// root node as JsonElement
.getAsJsonObject() // returns that element (the root)
// now considered as JsonObject
.getAsJsonObject("address"); // looks up "address" in the members
// map of the root, finds a JsonElement,
// returns that element considered as
// a JsonObject
// and that last is what you store in jsonObjectAddress.
每个JsonElement都是JsonPrimitive,JsonObject,JsonArray或JsonNull。我们的兴趣在于JsonObject;从定义上讲,它们被构造为其他领域。每个JsonObject都有一个名为“ members”的映射,该映射枚举对象的字段。
根对象(代表整个JSON字符串)具有名为“名称”,“地址”,“角色”等的字段,因此其映射包含键“名称”,“地址”,“角色”等等。表示“地址”的对象具有名为“街道”,“城市”等的字段,因此其映射包含键“街道”,“城市”等。