Skip to content

Commit

Permalink
Improve documentation (#2193)
Browse files Browse the repository at this point in the history
* Improve JsonElement subclasses javadoc and add tests

* Slightly improve JsonSerializer and JsonDeserializer javadoc

* Improve ReflectionAccessTest failure message

* Improve documentation regarding field and class exclusion
  • Loading branch information
Marcono1234 authored Sep 9, 2022
1 parent 2266ccd commit 847d7f6
Show file tree
Hide file tree
Showing 11 changed files with 133 additions and 43 deletions.
3 changes: 2 additions & 1 deletion UserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
* While serializing, a null field is omitted from the output.
* While deserializing, a missing entry in JSON results in setting the corresponding field in the object to its default value: null for object types, zero for numeric types, and false for booleans.
* If a field is _synthetic_, it is ignored and not included in JSON serialization or deserialization.
* Fields corresponding to the outer classes in inner classes, anonymous classes, and local classes are ignored and not included in serialization or deserialization.
* Fields corresponding to the outer classes in inner classes are ignored and not included in serialization or deserialization.
* Anonymous and local classes are excluded. They will be serialized as JSON `null` and when deserialized their JSON value is ignored and `null` is returned. Convert the classes to `static` nested classes to enable serialization and deserialization for them.

### <a name="TOC-Nested-Classes-including-Inner-Classes-"></a>Nested Classes (including Inner Classes)

Expand Down
9 changes: 3 additions & 6 deletions gson/src/main/java/com/google/gson/ExclusionStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,8 @@
package com.google.gson;

/**
* A strategy (or policy) definition that is used to decide whether or not a field or top-level
* class should be serialized or deserialized as part of the JSON output/input. For serialization,
* if the {@link #shouldSkipClass(Class)} method returns true then that class or field type
* will not be part of the JSON output. For deserialization, if {@link #shouldSkipClass(Class)}
* returns true, then it will not be set as part of the Java object structure.
* A strategy (or policy) definition that is used to decide whether or not a field or
* class should be serialized or deserialized as part of the JSON output/input.
*
* <p>The following are a few examples that shows how you can use this exclusion mechanism.
*
Expand Down Expand Up @@ -64,7 +61,7 @@
*
* <p>Now if you want to configure {@code Gson} to use a user defined exclusion strategy, then
* the {@code GsonBuilder} is required. The following is an example of how you can use the
* {@code GsonBuilder} to configure Gson to use one of the above sample:
* {@code GsonBuilder} to configure Gson to use one of the above samples:
* <pre class="code">
* ExclusionStrategy excludeStrings = new UserDefinedExclusionStrategy(String.class);
* Gson gson = new GsonBuilder()
Expand Down
43 changes: 39 additions & 4 deletions gson/src/main/java/com/google/gson/GsonBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,11 @@ public GsonBuilder setVersion(double ignoreVersionsAfter) {

/**
* Configures Gson to excludes all class fields that have the specified modifiers. By default,
* Gson will exclude all fields marked transient or static. This method will override that
* behavior.
* Gson will exclude all fields marked {@code transient} or {@code static}. This method will
* override that behavior.
*
* <p>This is a convenience method which behaves as if an {@link ExclusionStrategy} which
* excludes these fields was {@linkplain #setExclusionStrategies(ExclusionStrategy...) registered with this builder}.
*
* @param modifiers the field modifiers. You must use the modifiers specified in the
* {@link java.lang.reflect.Modifier} class. For example,
Expand Down Expand Up @@ -186,9 +189,12 @@ public GsonBuilder generateNonExecutableJson() {
}

/**
* Configures Gson to exclude all fields from consideration for serialization or deserialization
* Configures Gson to exclude all fields from consideration for serialization and deserialization
* that do not have the {@link com.google.gson.annotations.Expose} annotation.
*
* <p>This is a convenience method which behaves as if an {@link ExclusionStrategy} which excludes
* these fields was {@linkplain #setExclusionStrategies(ExclusionStrategy...) registered with this builder}.
*
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
*/
public GsonBuilder excludeFieldsWithoutExposeAnnotation() {
Expand Down Expand Up @@ -291,7 +297,20 @@ public GsonBuilder enableComplexMapKeySerialization() {
}

/**
* Configures Gson to exclude inner classes during serialization.
* Configures Gson to exclude inner classes (= non-{@code static} nested classes) during serialization
* and deserialization. This is a convenience method which behaves as if an {@link ExclusionStrategy}
* which excludes inner classes was {@linkplain #setExclusionStrategies(ExclusionStrategy...) registered with this builder}.
* This means inner classes will be serialized as JSON {@code null}, and will be deserialized as
* Java {@code null} with their JSON data being ignored. And fields with an inner class as type will
* be ignored during serialization and deserialization.
*
* <p>By default Gson serializes and deserializes inner classes, but ignores references to the
* enclosing instance. Deserialization might not be possible at all when {@link #disableJdkUnsafe()}
* is used (and no custom {@link InstanceCreator} is registered), or it can lead to unexpected
* {@code NullPointerException}s when the deserialized instance is used afterwards.
*
* <p>In general using inner classes with Gson should be avoided; they should be converted to {@code static}
* nested classes if possible.
*
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.3
Expand Down Expand Up @@ -369,6 +388,16 @@ public GsonBuilder setNumberToNumberStrategy(ToNumberStrategy numberToNumberStra
* The strategies are added to the existing strategies (if any); the existing strategies
* are not replaced.
*
* <p>Fields are excluded for serialization and deserialization when
* {@link ExclusionStrategy#shouldSkipField(FieldAttributes) shouldSkipField} returns {@code true},
* or when {@link ExclusionStrategy#shouldSkipClass(Class) shouldSkipClass} returns {@code true}
* for the field type. Gson behaves as if the field did not exist; its value is not serialized
* and on deserialization if a JSON member with this name exists it is skipped by default.<br>
* When objects of an excluded type (as determined by
* {@link ExclusionStrategy#shouldSkipClass(Class) shouldSkipClass}) are serialized a
* JSON null is written to output, and when deserialized the JSON value is skipped and
* {@code null} is returned.
*
* @param strategies the set of strategy object to apply during object (de)serialization.
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.4
Expand All @@ -389,6 +418,9 @@ public GsonBuilder setExclusionStrategies(ExclusionStrategy... strategies) {
* class) should be skipped then that field (or object) is skipped during its
* serialization.
*
* <p>See the documentation of {@link #setExclusionStrategies(ExclusionStrategy...)}
* for a detailed description of the effect of exclusion strategies.
*
* @param strategy an exclusion strategy to apply during serialization.
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.7
Expand All @@ -407,6 +439,9 @@ public GsonBuilder addSerializationExclusionStrategy(ExclusionStrategy strategy)
* class) should be skipped then that field (or object) is skipped during its
* deserialization.
*
* <p>See the documentation of {@link #setExclusionStrategies(ExclusionStrategy...)}
* for a detailed description of the effect of exclusion strategies.
*
* @param strategy an exclusion strategy to apply during deserialization.
* @return a reference to this {@code GsonBuilder} object to fulfill the "Builder" pattern
* @since 1.7
Expand Down
9 changes: 9 additions & 0 deletions gson/src/main/java/com/google/gson/JsonArray.java
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,20 @@ public boolean getAsBoolean() {
return getAsSingleElement().getAsBoolean();
}

/**
* Returns whether the other object is equal to this. This method only considers
* the other object to be equal if it is an instance of {@code JsonArray} and has
* equal elements in the same order.
*/
@Override
public boolean equals(Object o) {
return (o == this) || (o instanceof JsonArray && ((JsonArray) o).elements.equals(elements));
}

/**
* Returns the hash code of this array. This method calculates the hash code based
* on the elements of this array.
*/
@Override
public int hashCode() {
return elements.hashCode();
Expand Down
6 changes: 3 additions & 3 deletions gson/src/main/java/com/google/gson/JsonDeserializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import java.lang.reflect.Type;

/**
* <p>Interface representing a custom deserializer for Json. You should write a custom
* <p>Interface representing a custom deserializer for JSON. You should write a custom
* deserializer, if you are not happy with the default deserialization done by Gson. You will
* also need to register this deserializer through
* {@link GsonBuilder#registerTypeAdapter(Type, Object)}.</p>
Expand All @@ -42,9 +42,9 @@
* </pre>
*
* <p>The default deserialization of {@code Id(com.foo.MyObject.class, 20L)} will require the
* Json string to be <code>{"clazz":com.foo.MyObject,"value":20}</code>. Suppose, you already know
* JSON string to be <code>{"clazz":"com.foo.MyObject","value":20}</code>. Suppose, you already know
* the type of the field that the {@code Id} will be deserialized into, and hence just want to
* deserialize it from a Json string {@code 20}. You can achieve that by writing a custom
* deserialize it from a JSON string {@code 20}. You can achieve that by writing a custom
* deserializer:</p>
*
* <pre>
Expand Down
15 changes: 8 additions & 7 deletions gson/src/main/java/com/google/gson/JsonNull.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,33 @@
package com.google.gson;

/**
* A class representing a Json {@code null} value.
* A class representing a JSON {@code null} value.
*
* @author Inderjeet Singh
* @author Joel Leitch
* @since 1.2
*/
public final class JsonNull extends JsonElement {
/**
* Singleton for JsonNull
* Singleton for {@code JsonNull}.
*
* @since 1.8
*/
public static final JsonNull INSTANCE = new JsonNull();

/**
* Creates a new JsonNull object.
* Creates a new {@code JsonNull} object.
*
* @deprecated Deprecated since Gson version 1.8. Use {@link #INSTANCE} instead
* @deprecated Deprecated since Gson version 1.8, use {@link #INSTANCE} instead.
*/
@Deprecated
public JsonNull() {
// Do nothing
}

/**
* Returns the same instance since it is an immutable value
* Returns the same instance since it is an immutable value.
*
* @since 2.8.2
*/
@Override
Expand All @@ -51,15 +52,15 @@ public JsonNull deepCopy() {
}

/**
* All instances of JsonNull have the same hash code since they are indistinguishable
* All instances of {@code JsonNull} have the same hash code since they are indistinguishable.
*/
@Override
public int hashCode() {
return JsonNull.class.hashCode();
}

/**
* All instances of JsonNull are the same
* All instances of {@code JsonNull} are considered equal.
*/
@Override
public boolean equals(Object other) {
Expand Down
55 changes: 36 additions & 19 deletions gson/src/main/java/com/google/gson/JsonObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ public JsonObject() {
}

/**
* Creates a deep copy of this element and all its children
* Creates a deep copy of this element and all its children.
*
* @since 2.8.2
*/
@Override
Expand All @@ -55,7 +56,7 @@ public JsonObject deepCopy() {

/**
* 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
* can be an arbitrary {@link JsonElement}, thereby allowing you to build a full tree of JsonElements
* rooted at this node.
*
* @param property name of the member.
Expand All @@ -66,19 +67,20 @@ public void add(String property, JsonElement value) {
}

/**
* Removes the {@code property} from this {@link JsonObject}.
* Removes the {@code property} from this object.
*
* @param property name of the member that should be removed.
* @return the {@link JsonElement} object that is being removed.
* @return the {@link JsonElement} object that is being removed, or {@code null} if no
* member with this name exists.
* @since 1.3
*/
public JsonElement remove(String property) {
return members.remove(property);
}

/**
* Convenience method to add a primitive member. The specified value is converted to a
* JsonPrimitive of String.
* Convenience method to add a string member. The specified value is converted to a
* {@link JsonPrimitive} of String.
*
* @param property name of the member.
* @param value the string value associated with the member.
Expand All @@ -88,8 +90,8 @@ public void addProperty(String property, String value) {
}

/**
* Convenience method to add a primitive member. The specified value is converted to a
* JsonPrimitive of Number.
* Convenience method to add a number member. The specified value is converted to a
* {@link JsonPrimitive} of Number.
*
* @param property name of the member.
* @param value the number value associated with the member.
Expand All @@ -100,21 +102,21 @@ public void addProperty(String property, Number value) {

/**
* Convenience method to add a boolean member. The specified value is converted to a
* JsonPrimitive of Boolean.
* {@link JsonPrimitive} of Boolean.
*
* @param property name of the member.
* @param value the number value associated with the member.
* @param value the boolean value associated with the member.
*/
public void addProperty(String property, Boolean value) {
add(property, value == null ? JsonNull.INSTANCE : new JsonPrimitive(value));
}

/**
* Convenience method to add a char member. The specified value is converted to a
* JsonPrimitive of Character.
* {@link JsonPrimitive} of Character.
*
* @param property name of the member.
* @param value the number value associated with the member.
* @param value the char value associated with the member.
*/
public void addProperty(String property, Character value) {
add(property, value == null ? JsonNull.INSTANCE : new JsonPrimitive(value));
Expand Down Expand Up @@ -163,48 +165,63 @@ public boolean has(String memberName) {
* 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.
* @return the member matching the name, or {@code null} if no such member exists.
*/
public JsonElement get(String memberName) {
return members.get(memberName);
}

/**
* Convenience method to get the specified member as a JsonPrimitive element.
* Convenience method to get the specified member as a {@link JsonPrimitive}.
*
* @param memberName name of the member being requested.
* @return the JsonPrimitive corresponding to the specified member.
* @return the {@code JsonPrimitive} corresponding to the specified member, or {@code null} if no
* member with this name exists.
* @throws ClassCastException if the member is not of type {@code JsonPrimitive}.
*/
public JsonPrimitive getAsJsonPrimitive(String memberName) {
return (JsonPrimitive) members.get(memberName);
}

/**
* Convenience method to get the specified member as a JsonArray.
* Convenience method to get the specified member as a {@link JsonArray}.
*
* @param memberName name of the member being requested.
* @return the JsonArray corresponding to the specified member.
* @return the {@code JsonArray} corresponding to the specified member, or {@code null} if no
* member with this name exists.
* @throws ClassCastException if the member is not of type {@code JsonArray}.
*/
public JsonArray getAsJsonArray(String memberName) {
return (JsonArray) members.get(memberName);
}

/**
* Convenience method to get the specified member as a JsonObject.
* Convenience method to get the specified member as a {@link JsonObject}.
*
* @param memberName name of the member being requested.
* @return the JsonObject corresponding to the specified member.
* @return the {@code JsonObject} corresponding to the specified member, or {@code null} if no
* member with this name exists.
* @throws ClassCastException if the member is not of type {@code JsonObject}.
*/
public JsonObject getAsJsonObject(String memberName) {
return (JsonObject) members.get(memberName);
}

/**
* Returns whether the other object is equal to this. This method only considers
* the other object to be equal if it is an instance of {@code JsonObject} and has
* equal members, ignoring order.
*/
@Override
public boolean equals(Object o) {
return (o == this) || (o instanceof JsonObject
&& ((JsonObject) o).members.equals(members));
}

/**
* Returns the hash code of this object. This method calculates the hash code based
* on the members of this object, ignoring order.
*/
@Override
public int hashCode() {
return members.hashCode();
Expand Down
Loading

0 comments on commit 847d7f6

Please sign in to comment.