Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GSON: .isJsonNull() question

Tags:

json

null

gson

I am reading in a JSON file (using Google's GSON). One of my tests checks program's behavior in event file a given key is missing.

JsonElement value = e.getAsJsonObject().get(ENVIRONMENT);

My expectation is that when .get(ing) this key, i would get null. Turns out i do. When i .get(ENVIRONMENT), value returned is null.

When i test it, i actually get a "not null". Weird, considering, GSON's javadoc says "provides check for verifying if this element represents a null value or not"

if (value.isJsonNull()) {
    System.out.println("null");
} else {
    System.out.println("not null");
}

Please help me better understand this.

like image 382
James Raitsev Avatar asked Jun 06 '11 14:06

James Raitsev


1 Answers

Never mind my first answer below. I'd read the question too quickly.

It looks like this is a simple case of the documents lying -- or at least being misunderstood. Fortunately, code does not lie so easily and Gson is an open source project.

Here's JsonObject.get(String):

  /**
   * Returns the member with the specified name.
   *
   * @param memberName name of the member that is being requested.
   * @return the member matching the name. Null if no such member exists.
   */
  public JsonElement get(String memberName) {
    if (members.containsKey(memberName)) {
      JsonElement member = members.get(memberName);
      return member == null ? JsonNull.INSTANCE : member;
    }
    return null;
  }

and here's where members is populated:

  /**
   * Adds a member, which is a name-value pair, to self. The name must be a String, but the value
   * can be an arbitrary JsonElement, thereby allowing you to build a full tree of JsonElements
   * rooted at this node.
   *
   * @param property name of the member.
   * @param value the member object.
   */
  public void add(String property, JsonElement value) {
    if (value == null) {
      value = JsonNull.INSTANCE;
    }
    members.put($Gson$Preconditions.checkNotNull(property), value);
  }

Calls to add to members are made for every member defined in the Java class -- it's not based on what's in the JSON. (For those interested, the visitFieldsReflectively method in ReflectingFieldNavigator populates members.)

So, I suppose the confusion is surrounding the meaning of "member" in the clause "if no such member exists". Based on the code, I gather that the author of the JavaDoc was referring to a member defined in the Java class. To the casual user of the Gson API -- like myself -- I assumed that "member" referred to an object element in the JSON.

Now, is this issue clear?

====

First answer based on quick read of question (retained for useful links):

A null reference is not a JsonNull value. (value == null) is not the same as value.isJsonNull(). They are very different.

The docs describe that the call to JsonObject.get(String) returns "[n]ull if no such member exists." They do not say that JsonNull is returned.

The call to JsonElement.isJsonNull() is not checking whether the JsonElement reference is a null reference. In fact, if it were a null reference, calling a method on it would throw a NullPointerException. It's checking whether it's a JsonNull instance.

like image 145
Programmer Bruce Avatar answered Oct 23 '22 11:10

Programmer Bruce