简体   繁体   中英

How child class Instance variable got in touch with Parent class Instance

I'm trying to understand parent and child class instance scope or their behaviour in below code snippet. (Going through GSON framework to undersatand functionality)

private static JsonObject jsonObjectAddress = new JsonObject();
jsonObjectAddress = jsonParser.parse(bufferRead).getAsJsonObject().getAsJsonObject("address");
Set<Entry<String, JsonElement>> entrySetProperties = jsonObjectAddress.entrySet();

Want to understand:

jsonParser.parse(bufferRead) returns the JsonElement class instance which is a parent class of JsonObject class.

And JsonObject class is having below Instnce variable in it and it consists of all JSON attributes with key value pair.

private final LinkedTreeMap<String, JsonElement> members =
      new LinkedTreeMap<String, JsonElement>();

Am just curious to know, Where and who is filling this members , becasue its present in child's class as instance variable and jsonParser.parse(bufferRead) returns only JsonElement instance ...!

May I know please how its working...? ANy help would be appreciated to learn more...!

Update:

When I run this

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());
}

It gives me following result

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"}

Above result is a value of member indtance variable of JsonObject class. But if you see one of the value in member set is JsonObject too itself.

So If I run like this

jsonObjectAddress = jsonParser.parse(bufferRead).getAsJsonObject().getAsJsonObject("address");

It represent that same value of type JsonObject which is stored against key name addreess in member and shows results like this

class com.google.gson.JsonPrimitive
street:"BTM 1st Stage"
class com.google.gson.JsonPrimitive
city:"Bangalore"
class com.google.gson.JsonPrimitive
zipcode:560100

Am confused here, address key in member is having JsonObject , so when we extract only address`, then how it can return entryset()...?

The parser creates a tree of JsonElements as a result of parsing the JSON string, and its return value is the element that is the root of this tree. The answer to who is "responsible" for filling in the members set is the parser; it's what the parser does to parse the input.

There is no "getting in touch" to be done; there is a data structure that is equivalent to the JSON. For example if your JSON is

{ "stuff" : { "foo" : "F" , "bar" : "B" } }

then the map in the top-level JsonObject has one entry, keyed as "stuff", and the value of that entry is a JsonObject whose map has two entries, keyed as "foo" and "bar", whose values are JsonPrimitive values, in this case strings.

Subsequent "get" operations retrieve the nodes from this tree.


When you wrote this:

private static JsonObject jsonObjectAddress = new JsonObject();

you allocated a new JsonObject which is never used, because on the next line

 jsonObjectAddress = ...

you set the variable to a different JsonObject, one that exists in the tree structure created by the parser.


Edited some more:

Perhaps I misunderstood your use of parent/child terminology. I construed it to refer to the parent/child relationship in the tree of objects. But it seems you also refer to superclass/subclass relationships.

I think you're looking at it in the wrong way. There is not a separate "JsonObject instance" and "JsonElement instance". There is (conceptually at least) just one object; the object is a JsonElement and (in this particular case) it is also a JsonObject.

That's just how Java classes work.

So, when you get a node from the parse tree, it is treated as an JsonElement because that's the base type for all possibilities. The element may be a JsonObject, a JsonPrimitive, a JsonArray, or a JsonNull. When you call "getAsJsonObject", you're basically saying you now want to treat the element you've got as an object (and internally GSON will check that it makes sense to do so).


Added after your update to the question.

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.

Every JsonElement is a JsonPrimitive, JsonObject, JsonArray, or JsonNull. Our interest is with JsonObject; they are by definition structured into further fields. Every JsonObject will have a map named 'members' that enumerates the fields of the object.

The root object (representing the JSON string as a whole) has fields named "name", "address", "role", etc., and thus its map contains keys "name", "address", "role", etc. The object representing "address" has fields named "street", "city", etc., and thus its map contains keys "street", "city", etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM