Improve documentation (#2193)
* Improve JsonElement subclasses javadoc and add tests * Slightly improve JsonSerializer and JsonDeserializer javadoc * Improve ReflectionAccessTest failure message * Improve documentation regarding field and class exclusion
This commit is contained in:
parent
2266ccdd67
commit
847d7f6638
@ -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)
|
||||
|
||||
|
@ -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.
|
||||
*
|
||||
@ -64,7 +61,7 @@ package com.google.gson;
|
||||
*
|
||||
* <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()
|
||||
|
@ -156,8 +156,11 @@ public final class GsonBuilder {
|
||||
|
||||
/**
|
||||
* 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,
|
||||
@ -186,9 +189,12 @@ public final class GsonBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
@ -291,7 +297,20 @@ public final class GsonBuilder {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -369,6 +388,16 @@ public final class GsonBuilder {
|
||||
* 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
|
||||
@ -389,6 +418,9 @@ public final class GsonBuilder {
|
||||
* 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
|
||||
@ -407,6 +439,9 @@ public final class GsonBuilder {
|
||||
* 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
|
||||
|
@ -387,11 +387,20 @@ public final class JsonArray extends JsonElement implements Iterable<JsonElement
|
||||
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();
|
||||
|
@ -19,7 +19,7 @@ package com.google.gson;
|
||||
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>
|
||||
@ -42,9 +42,9 @@ import java.lang.reflect.Type;
|
||||
* </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>
|
||||
|
@ -17,7 +17,7 @@
|
||||
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
|
||||
@ -25,16 +25,16 @@ package com.google.gson;
|
||||
*/
|
||||
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() {
|
||||
@ -42,7 +42,8 @@ public final class JsonNull extends JsonElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -51,7 +52,7 @@ public final class JsonNull extends JsonElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
@ -59,7 +60,7 @@ public final class JsonNull extends JsonElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* All instances of JsonNull are the same
|
||||
* All instances of {@code JsonNull} are considered equal.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
|
@ -41,7 +41,8 @@ public final class JsonObject extends JsonElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -55,7 +56,7 @@ public final class JsonObject extends JsonElement {
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -66,10 +67,11 @@ public final class JsonObject extends JsonElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
@ -77,8 +79,8 @@ public final class JsonObject extends JsonElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -88,8 +90,8 @@ public final class JsonObject extends JsonElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@ -100,10 +102,10 @@ public final class JsonObject extends JsonElement {
|
||||
|
||||
/**
|
||||
* 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));
|
||||
@ -111,10 +113,10 @@ public final class JsonObject extends JsonElement {
|
||||
|
||||
/**
|
||||
* 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));
|
||||
@ -163,48 +165,63 @@ public final class JsonObject extends JsonElement {
|
||||
* 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();
|
||||
|
@ -78,6 +78,7 @@ public final class JsonPrimitive extends JsonElement {
|
||||
|
||||
/**
|
||||
* Returns the same value as primitives are immutable.
|
||||
*
|
||||
* @since 2.8.2
|
||||
*/
|
||||
@Override
|
||||
@ -243,6 +244,9 @@ public final class JsonPrimitive extends JsonElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the hash code of this object.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
if (value == null) {
|
||||
@ -260,6 +264,11 @@ public final class JsonPrimitive extends JsonElement {
|
||||
return value.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 JsonPrimitive} and
|
||||
* has an equal value.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
|
@ -19,7 +19,7 @@ package com.google.gson;
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
/**
|
||||
* Interface representing a custom serializer for Json. You should write a custom serializer, if
|
||||
* Interface representing a custom serializer for JSON. You should write a custom serializer, if
|
||||
* you are not happy with the default serialization done by Gson. You will also need to register
|
||||
* this serializer through {@link com.google.gson.GsonBuilder#registerTypeAdapter(Type, Object)}.
|
||||
*
|
||||
@ -43,7 +43,7 @@ import java.lang.reflect.Type;
|
||||
* </pre>
|
||||
*
|
||||
* <p>The default serialization of {@code Id(com.foo.MyObject.class, 20L)} will be
|
||||
* <code>{"clazz":com.foo.MyObject,"value":20}</code>. Suppose, you just want the output to be
|
||||
* <code>{"clazz":"com.foo.MyObject","value":20}</code>. Suppose, you just want the output to be
|
||||
* the value instead, which is {@code 20} in this case. You can achieve that by writing a custom
|
||||
* serializer:</p>
|
||||
*
|
||||
|
@ -50,6 +50,8 @@ public class JsonObjectTest extends TestCase {
|
||||
assertEquals(value, removedElement);
|
||||
assertFalse(jsonObj.has(propertyName));
|
||||
assertNull(jsonObj.get(propertyName));
|
||||
|
||||
assertNull(jsonObj.remove(propertyName));
|
||||
}
|
||||
|
||||
public void testAddingNullPropertyValue() throws Exception {
|
||||
@ -170,6 +172,22 @@ public class JsonObjectTest extends TestCase {
|
||||
assertFalse(b.equals(a));
|
||||
}
|
||||
|
||||
public void testEqualsHashCodeIgnoringOrder() {
|
||||
JsonObject a = new JsonObject();
|
||||
JsonObject b = new JsonObject();
|
||||
|
||||
a.addProperty("1", true);
|
||||
b.addProperty("2", false);
|
||||
|
||||
a.addProperty("2", false);
|
||||
b.addProperty("1", true);
|
||||
|
||||
assertEquals(Arrays.asList("1", "2"), new ArrayList<>(a.keySet()));
|
||||
assertEquals(Arrays.asList("2", "1"), new ArrayList<>(b.keySet()));
|
||||
|
||||
MoreAsserts.assertEqualsAndHashCode(a, b);
|
||||
}
|
||||
|
||||
public void testSize() {
|
||||
JsonObject o = new JsonObject();
|
||||
assertEquals(0, o.size());
|
||||
|
@ -8,6 +8,7 @@ import static org.junit.Assert.fail;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonIOException;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
@ -111,8 +112,10 @@ public class ReflectionAccessTest {
|
||||
// But deserialization should fail
|
||||
Class<?> internalClass = Collections.emptyList().getClass();
|
||||
try {
|
||||
gson.fromJson("{}", internalClass);
|
||||
gson.fromJson("[]", internalClass);
|
||||
fail("Missing exception; test has to be run with `--illegal-access=deny`");
|
||||
} catch (JsonSyntaxException e) {
|
||||
fail("Unexpected exception; test has to be run with `--illegal-access=deny`");
|
||||
} catch (JsonIOException expected) {
|
||||
assertTrue(expected.getMessage().startsWith(
|
||||
"Failed making constructor 'java.util.Collections$EmptyList#EmptyList()' accessible; "
|
||||
|
Loading…
Reference in New Issue
Block a user