Code cleanup and some minor performance fixes.

This commit is contained in:
Joel Leitch 2009-01-20 01:36:54 +00:00
parent 2cec661ff0
commit 6a80791f13
17 changed files with 110 additions and 124 deletions

View File

@ -454,8 +454,8 @@ final class DefaultTypeAdapters {
if (value == null) { if (value == null) {
valueElement = JsonNull.createJsonNull(); valueElement = JsonNull.createJsonNull();
} else { } else {
Type childType = (childGenericType == null) ? Type childType = (childGenericType == null)
childType = value.getClass() : childGenericType; ? value.getClass() : childGenericType;
valueElement = context.serialize(value, childType); valueElement = context.serialize(value, childType);
} }
map.add(String.valueOf(entry.getKey()), valueElement); map.add(String.valueOf(entry.getKey()), valueElement);

View File

@ -26,7 +26,6 @@ import java.lang.reflect.Type;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger;
/** /**
* This is the main class for using Gson. Gson is typically used by first constructing a * This is the main class for using Gson. Gson is typically used by first constructing a
@ -76,6 +75,7 @@ public final class Gson {
// constructor instead. At the minimum, mark those methods private. // constructor instead. At the minimum, mark those methods private.
private static final String NULL_STRING = "null"; private static final String NULL_STRING = "null";
// Default instances of plug-ins // Default instances of plug-ins
static final ModifierBasedExclusionStrategy DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY = static final ModifierBasedExclusionStrategy DEFAULT_MODIFIER_BASED_EXCLUSION_STRATEGY =
new ModifierBasedExclusionStrategy(true, new int[] { Modifier.TRANSIENT, Modifier.STATIC }); new ModifierBasedExclusionStrategy(true, new int[] { Modifier.TRANSIENT, Modifier.STATIC });
@ -83,8 +83,6 @@ public final class Gson {
static final FieldNamingStrategy DEFAULT_NAMING_POLICY = static final FieldNamingStrategy DEFAULT_NAMING_POLICY =
new SerializedNameAnnotationInterceptingNamingPolicy(new JavaFieldNamingPolicy()); new SerializedNameAnnotationInterceptingNamingPolicy(new JavaFieldNamingPolicy());
static final Logger logger = Logger.getLogger(Gson.class.getName());
private final ExclusionStrategy strategy; private final ExclusionStrategy strategy;
private final FieldNamingStrategy fieldNamingPolicy; private final FieldNamingStrategy fieldNamingPolicy;
private final MappedObjectConstructor objectConstructor; private final MappedObjectConstructor objectConstructor;
@ -402,15 +400,16 @@ public final class Gson {
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder("{"); StringBuilder sb = new StringBuilder("{")
sb.append("serializeNulls:").append(serializeNulls); .append("serializeNulls:").append(serializeNulls)
sb.append(",serializers:").append(serializers); .append(",serializers:").append(serializers)
sb.append(",deserializers:").append(deserializers); .append(",deserializers:").append(deserializers)
// using the name instanceCreator instead of ObjectConstructor since the users of Gson are
// more familiar with the concept of Instance Creators. Moreover, the objectConstructor is // using the name instanceCreator instead of ObjectConstructor since the users of Gson are
// just a utility class around instance creators, and its toString() only displays them. // more familiar with the concept of Instance Creators. Moreover, the objectConstructor is
sb.append(",instanceCreators:").append(objectConstructor); // just a utility class around instance creators, and its toString() only displays them.
sb.append("}"); .append(",instanceCreators:").append(objectConstructor)
return sb.toString(); .append("}");
return sb.toString();
} }
} }

View File

@ -436,8 +436,8 @@ public final class GsonBuilder {
dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle, timeStyle); dateTypeAdapter = new DefaultDateTypeAdapter(dateStyle, timeStyle);
} }
if (dateTypeAdapter != null if (dateTypeAdapter != null
&& !serializers.hasAnyHandlerFor(Date.class) && !serializers.hasSpecificHandlerFor(Date.class)
&& !deserializers.hasAnyHandlerFor(Date.class)) { && !deserializers.hasSpecificHandlerFor(Date.class)) {
serializers.register(Date.class, dateTypeAdapter); serializers.register(Date.class, dateTypeAdapter);
deserializers.register(Date.class, dateTypeAdapter); deserializers.register(Date.class, dateTypeAdapter);
} }

View File

@ -16,6 +16,7 @@
package com.google.gson; package com.google.gson;
import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Collections; import java.util.Collections;
@ -291,7 +292,7 @@ public final class JsonArray extends JsonElement implements Iterable<JsonElement
} }
@Override @Override
protected void toString(StringBuilder sb) { protected void toString(Appendable sb) throws IOException {
sb.append('['); sb.append('[');
boolean first = true; boolean first = true;
for (JsonElement element : elements) { for (JsonElement element : elements) {

View File

@ -35,7 +35,7 @@ final class JsonCompactFormatter implements JsonFormatter {
} }
public void visitPrimitive(JsonPrimitive primitive) throws IOException { public void visitPrimitive(JsonPrimitive primitive) throws IOException {
writer.append(primitive.toString()); primitive.toString(writer);
} }
public void visitNull() throws IOException { public void visitNull() throws IOException {
@ -51,7 +51,7 @@ final class JsonCompactFormatter implements JsonFormatter {
if (!isFirst) { if (!isFirst) {
writer.append(','); writer.append(',');
} }
writer.append(member.toString()); member.toString(writer);
} }
public void visitArrayMember(JsonArray parent, JsonArray member, public void visitArrayMember(JsonArray parent, JsonArray member,
@ -90,7 +90,7 @@ final class JsonCompactFormatter implements JsonFormatter {
writer.append('"'); writer.append('"');
writer.append(memberName); writer.append(memberName);
writer.append("\":"); writer.append("\":");
writer.append(member.toString()); member.toString(writer);
} }
public void visitObjectMember(JsonObject parent, String memberName, JsonArray member, public void visitObjectMember(JsonObject parent, String memberName, JsonArray member,

View File

@ -17,7 +17,6 @@
package com.google.gson; package com.google.gson;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.logging.Logger;
/** /**
* Abstract data value container for the {@link ObjectNavigator.Visitor} * Abstract data value container for the {@link ObjectNavigator.Visitor}
@ -29,8 +28,6 @@ import java.util.logging.Logger;
*/ */
abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor { abstract class JsonDeserializationVisitor<T> implements ObjectNavigator.Visitor {
protected static Logger logger = Logger.getLogger(JsonDeserializationVisitor.class.getName());
protected final ObjectNavigatorFactory factory; protected final ObjectNavigatorFactory factory;
protected final ObjectConstructor objectConstructor; protected final ObjectConstructor objectConstructor;
protected final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers; protected final ParameterizedTypeHandlerMap<JsonDeserializer<?>> deserializers;

View File

@ -16,6 +16,7 @@
package com.google.gson; package com.google.gson;
import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
@ -311,10 +312,14 @@ public abstract class JsonElement {
*/ */
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); try {
toString(sb); StringBuilder sb = new StringBuilder();
return sb.toString(); toString(sb);
return sb.toString();
} catch (IOException e) {
throw new RuntimeException(e);
}
} }
protected abstract void toString(StringBuilder sb); protected abstract void toString(Appendable sb) throws IOException;
} }

View File

@ -61,10 +61,7 @@ class JsonEscapingVisitor extends DelegatingJsonElementVisitor {
private JsonPrimitive escapeJsonPrimitive(JsonPrimitive member) { private JsonPrimitive escapeJsonPrimitive(JsonPrimitive member) {
if (member.isString()) { if (member.isString()) {
String memberValue = member.getAsString(); String memberValue = member.getAsString();
String escapedValue = escaper.escapeJsonString(memberValue); member.setValue(escaper.escapeJsonString(memberValue));
if (!escapedValue.equals(memberValue)) {
member.setValue(escapedValue);
}
} }
return member; return member;
} }

View File

@ -16,6 +16,8 @@
package com.google.gson; package com.google.gson;
import java.io.IOException;
/** /**
* A class representing a Json {@code null} value. * A class representing a Json {@code null} value.
* *
@ -34,7 +36,7 @@ public final class JsonNull extends JsonElement {
} }
@Override @Override
protected void toString(StringBuilder sb) { protected void toString(Appendable sb) throws IOException {
sb.append("null"); sb.append("null");
} }

View File

@ -16,6 +16,7 @@
package com.google.gson; package com.google.gson;
import java.io.IOException;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -189,7 +190,7 @@ public final class JsonObject extends JsonElement {
} }
@Override @Override
protected void toString(StringBuilder sb) { protected void toString(Appendable sb) throws IOException {
sb.append('{'); sb.append('{');
boolean first = true; boolean first = true;
for (Map.Entry<String, JsonElement> entry : members.entrySet()) { for (Map.Entry<String, JsonElement> entry : members.entrySet()) {

View File

@ -16,6 +16,7 @@
package com.google.gson; package com.google.gson;
import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
@ -305,16 +306,13 @@ public final class JsonPrimitive extends JsonElement {
} }
@Override @Override
protected void toString(StringBuilder sb) { protected void toString(Appendable sb) throws IOException {
if (value != null) { if (value instanceof String) {
if (value instanceof String) { sb.append('"');
sb.append('"'); sb.append((String) value);
sb.append(value); sb.append('"');
sb.append('"'); } else {
sb.append(value.toString());
} else {
sb.append(value);
}
} }
} }

View File

@ -103,17 +103,13 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
private void addAsArrayElement(Type elementType, Object elementValue) { private void addAsArrayElement(Type elementType, Object elementValue) {
if (elementValue == null) { if (elementValue == null) {
addNullAsArrayElement(); root.getAsJsonArray().add(JsonNull.createJsonNull());
} else { } else {
JsonElement childElement = getJsonElementForChild(elementType, elementValue); JsonElement childElement = getJsonElementForChild(elementType, elementValue);
root.getAsJsonArray().add(childElement); root.getAsJsonArray().add(childElement);
} }
} }
private void addNullAsArrayElement() {
root.getAsJsonArray().add(null);
}
private JsonElement getJsonElementForChild(Type fieldType, Object fieldValue) { private JsonElement getJsonElementForChild(Type fieldType, Object fieldValue) {
ObjectNavigator on = factory.create(fieldValue, fieldType); ObjectNavigator on = factory.create(fieldValue, fieldType);
JsonSerializationVisitor childVisitor = JsonSerializationVisitor childVisitor =
@ -160,7 +156,7 @@ final class JsonSerializationVisitor implements ObjectNavigator.Visitor {
} }
private void assignToRoot(JsonElement newRoot) { private void assignToRoot(JsonElement newRoot) {
Preconditions.checkArgument(root == null); Preconditions.checkNotNull(newRoot);
root = newRoot; root = newRoot;
} }

View File

@ -34,7 +34,7 @@ final class JsonTreeNavigator {
} }
public void navigate(JsonElement element) throws IOException { public void navigate(JsonElement element) throws IOException {
if (element == null || element.isJsonNull()) { if (element.isJsonNull()) {
visitor.visitNull(); visitor.visitNull();
} else if (element.isJsonArray()) { } else if (element.isJsonArray()) {
JsonArray array = element.getAsJsonArray(); JsonArray array = element.getAsJsonArray();
@ -68,25 +68,23 @@ final class JsonTreeNavigator {
*/ */
private boolean visitChild(JsonObject parent, String childName, JsonElement child, private boolean visitChild(JsonObject parent, String childName, JsonElement child,
boolean isFirst) throws IOException { boolean isFirst) throws IOException {
if (child != null) { if (child.isJsonNull()) {
if (child.isJsonNull()) { if (visitNulls) {
if (visitNulls) { visitor.visitNullObjectMember(parent, childName, isFirst);
visitor.visitNullObjectMember(parent, childName, isFirst); navigate(child.getAsJsonNull());
navigate(child.getAsJsonNull()); } else { // Null value is being skipped.
} else { // Null value is being skipped. return false;
return false;
}
} else if (child.isJsonArray()) {
JsonArray childAsArray = child.getAsJsonArray();
visitor.visitObjectMember(parent, childName, childAsArray, isFirst);
navigate(childAsArray);
} else if (child.isJsonObject()) {
JsonObject childAsObject = child.getAsJsonObject();
visitor.visitObjectMember(parent, childName, childAsObject, isFirst);
navigate(childAsObject);
} else { // is a JsonPrimitive
visitor.visitObjectMember(parent, childName, child.getAsJsonPrimitive(), isFirst);
} }
} else if (child.isJsonArray()) {
JsonArray childAsArray = child.getAsJsonArray();
visitor.visitObjectMember(parent, childName, childAsArray, isFirst);
navigate(childAsArray);
} else if (child.isJsonObject()) {
JsonObject childAsObject = child.getAsJsonObject();
visitor.visitObjectMember(parent, childName, childAsObject, isFirst);
navigate(childAsObject);
} else { // is a JsonPrimitive
visitor.visitObjectMember(parent, childName, child.getAsJsonPrimitive(), isFirst);
} }
return true; return true;
} }
@ -95,9 +93,9 @@ final class JsonTreeNavigator {
* Returns true if the child was visited, false if it was skipped. * Returns true if the child was visited, false if it was skipped.
*/ */
private void visitChild(JsonArray parent, JsonElement child, boolean isFirst) throws IOException { private void visitChild(JsonArray parent, JsonElement child, boolean isFirst) throws IOException {
if (child == null || child.isJsonNull()) { if (child.isJsonNull()) {
visitor.visitNullArrayMember(parent, isFirst); visitor.visitNullArrayMember(parent, isFirst);
navigate(null); navigate(child);
} else if (child.isJsonArray()) { } else if (child.isJsonArray()) {
JsonArray childAsArray = child.getAsJsonArray(); JsonArray childAsArray = child.getAsJsonArray();
visitor.visitArrayMember(parent, childAsArray, isFirst); visitor.visitArrayMember(parent, childAsArray, isFirst);

View File

@ -35,15 +35,15 @@ import java.util.logging.Logger;
* @author Joel Leitch * @author Joel Leitch
*/ */
final class MappedObjectConstructor implements ObjectConstructor { final class MappedObjectConstructor implements ObjectConstructor {
private final Logger log = Logger.getLogger(getClass().getName()); private static final Logger log = Logger.getLogger(MappedObjectConstructor.class.getName());
private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreatorMap = private final ParameterizedTypeHandlerMap<InstanceCreator<?>> instanceCreatorMap =
new ParameterizedTypeHandlerMap<InstanceCreator<?>>(); new ParameterizedTypeHandlerMap<InstanceCreator<?>>();
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T construct(Type typeOfT) { public <T> T construct(Type typeOfT) {
if (instanceCreatorMap.hasAnyHandlerFor(typeOfT)) { InstanceCreator<T> creator = (InstanceCreator<T>) instanceCreatorMap.getHandlerFor(typeOfT);
InstanceCreator<T> creator = (InstanceCreator<T>) instanceCreatorMap.getHandlerFor(typeOfT); if (creator != null) {
return creator.createInstance(typeOfT); return creator.createInstance(typeOfT);
} }
return (T) constructWithNoArgConstructor(typeOfT); return (T) constructWithNoArgConstructor(typeOfT);

View File

@ -16,40 +16,46 @@
package com.google.gson; package com.google.gson;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger;
/** /**
* A map that provides ability to associate handlers for a specific type or all of its sub-types * A map that provides ability to associate handlers for a specific type or all
* * of its sub-types
*
* @author Inderjeet Singh * @author Inderjeet Singh
* @author Joel Leitch * @author Joel Leitch
* *
* @param <T> The handler that will be looked up by type * @param <T>
* The handler that will be looked up by type
*/ */
final class ParameterizedTypeHandlerMap<T> { final class ParameterizedTypeHandlerMap<T> {
private static final Logger logger =
Logger.getLogger(ParameterizedTypeHandlerMap.class.getName());
private final Map<Type, T> map = new HashMap<Type, T>(); private final Map<Type, T> map = new HashMap<Type, T>();
private boolean modifiable = true; private boolean modifiable = true;
public synchronized void register(Type typeOfT, T value) { public synchronized void register(Type typeOfT, T value) {
if (!modifiable) { if (!modifiable) {
throw new IllegalStateException("Attempted to modify an unmodifiable map."); throw new IllegalStateException(
"Attempted to modify an unmodifiable map.");
} }
if (hasSpecificHandlerFor(typeOfT)) { if (hasSpecificHandlerFor(typeOfT)) {
Gson.logger.log(Level.WARNING, "Overriding the existing type handler for " + typeOfT); logger.log(Level.WARNING,
"Overriding the existing type handler for " + typeOfT);
} }
map.put(typeOfT, value); map.put(typeOfT, value);
} }
public synchronized void registerIfAbsent(ParameterizedTypeHandlerMap<T> other) { public synchronized void registerIfAbsent(ParameterizedTypeHandlerMap<T> other) {
if (!modifiable) { if (!modifiable) {
throw new IllegalStateException("Attempted to modify an unmodifiable map."); throw new IllegalStateException(
"Attempted to modify an unmodifiable map.");
} }
for (Map.Entry<Type, T> entry : other.entrySet()) { for (Map.Entry<Type, T> entry : other.entrySet()) {
if (!map.containsKey(entry.getKey())) { if (!map.containsKey(entry.getKey())) {
@ -60,7 +66,8 @@ final class ParameterizedTypeHandlerMap<T> {
public synchronized void registerIfAbsent(Type typeOfT, T value) { public synchronized void registerIfAbsent(Type typeOfT, T value) {
if (!modifiable) { if (!modifiable) {
throw new IllegalStateException("Attempted to modify an unmodifiable map."); throw new IllegalStateException(
"Attempted to modify an unmodifiable map.");
} }
if (!map.containsKey(typeOfT)) { if (!map.containsKey(typeOfT)) {
register(typeOfT, value); register(typeOfT, value);
@ -72,18 +79,15 @@ final class ParameterizedTypeHandlerMap<T> {
} }
public synchronized T getHandlerFor(Type type) { public synchronized T getHandlerFor(Type type) {
T handler = getRawHandlerFor(type); T handler = map.get(type);
Type rawType = type;
if (handler == null && type instanceof ParameterizedType) {
// a handler for a non-generic version may be registered, so use that
rawType = ((ParameterizedType)type).getRawType();
handler = map.get(rawType);
}
// Check for map or collection
if (handler == null) { if (handler == null) {
if (rawType instanceof Class) { Class<?> rawClass = TypeUtils.toRawClass(type);
Class<?> rawClass = (Class<?>) rawType; if (rawClass != type) {
handler = getHandlerFor(rawClass);
}
// Check for map or collection
if (handler == null) {
if (Map.class.isAssignableFrom(rawClass)) { if (Map.class.isAssignableFrom(rawClass)) {
handler = map.get(Map.class); handler = map.get(Map.class);
} else if (Collection.class.isAssignableFrom(rawClass)) { } else if (Collection.class.isAssignableFrom(rawClass)) {
@ -95,27 +99,6 @@ final class ParameterizedTypeHandlerMap<T> {
} }
return handler; return handler;
} }
private synchronized T getRawHandlerFor(Type type) {
if (type instanceof Map) {
return map.get(Map.class);
} else if (type instanceof Collection) {
return map.get(Collection.class);
} else {
T handler = map.get(type);
if (handler == null) {
Class<?> rawClass = TypeUtils.toRawClass(type);
if (rawClass != type) {
handler = getHandlerFor(rawClass);
}
}
return handler;
}
}
public synchronized boolean hasAnyHandlerFor(Type type) {
return getHandlerFor(type) != null;
}
public synchronized boolean hasSpecificHandlerFor(Type type) { public synchronized boolean hasSpecificHandlerFor(Type type) {
return map.containsKey(type); return map.containsKey(type);
@ -132,7 +115,7 @@ final class ParameterizedTypeHandlerMap<T> {
public synchronized Set<Map.Entry<Type, T>> entrySet() { public synchronized Set<Map.Entry<Type, T>> entrySet() {
return map.entrySet(); return map.entrySet();
} }
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder("{"); StringBuilder sb = new StringBuilder("{");
@ -148,7 +131,7 @@ final class ParameterizedTypeHandlerMap<T> {
} }
return sb.toString(); return sb.toString();
} }
private String typeToString(Type type) { private String typeToString(Type type) {
return TypeUtils.toRawClass(type).getSimpleName(); return TypeUtils.toRawClass(type).getSimpleName();
} }

View File

@ -39,7 +39,7 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
public void testNullMap() throws Exception { public void testNullMap() throws Exception {
assertFalse(paramMap.hasSpecificHandlerFor(String.class)); assertFalse(paramMap.hasSpecificHandlerFor(String.class));
assertFalse(paramMap.hasAnyHandlerFor(String.class)); assertNull(paramMap.getHandlerFor(String.class));
assertNull(paramMap.getHandlerFor(String.class)); assertNull(paramMap.getHandlerFor(String.class));
} }
@ -50,8 +50,8 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
assertFalse(paramMap.hasSpecificHandlerFor(specificType)); assertFalse(paramMap.hasSpecificHandlerFor(specificType));
assertTrue(paramMap.hasSpecificHandlerFor(List.class)); assertTrue(paramMap.hasSpecificHandlerFor(List.class));
assertTrue(paramMap.hasAnyHandlerFor(specificType)); assertNotNull(paramMap.getHandlerFor(specificType));
assertTrue(paramMap.hasAnyHandlerFor(List.class)); assertNotNull(paramMap.getHandlerFor(List.class));
assertEquals(handler, paramMap.getHandlerFor(specificType)); assertEquals(handler, paramMap.getHandlerFor(specificType));
} }
@ -62,8 +62,8 @@ public class ParameterizedTypeHandlerMapTest extends TestCase {
assertTrue(paramMap.hasSpecificHandlerFor(specificType)); assertTrue(paramMap.hasSpecificHandlerFor(specificType));
assertFalse(paramMap.hasSpecificHandlerFor(List.class)); assertFalse(paramMap.hasSpecificHandlerFor(List.class));
assertTrue(paramMap.hasAnyHandlerFor(specificType)); assertNotNull(paramMap.getHandlerFor(specificType));
assertFalse(paramMap.hasAnyHandlerFor(List.class)); assertNull(paramMap.getHandlerFor(List.class));
assertEquals(handler, paramMap.getHandlerFor(specificType)); assertEquals(handler, paramMap.getHandlerFor(specificType));
} }

View File

@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
package com.google.gson.functional; package com.google.gson.functional;
import com.google.gson.Gson; import com.google.gson.Gson;
@ -82,6 +83,14 @@ public class ArrayTest extends TestCase {
assertEquals(expected[i], target[i]); assertEquals(expected[i], target[i]);
} }
} }
public void testNullsInArrayWithSerializeNullPropertySetSerialization() {
gson = new GsonBuilder().serializeNulls().create();
String[] array = {"foo", null, "bar"};
String expected = "[\"foo\",null,\"bar\"]";
String json = gson.toJson(array);
assertEquals(expected, json);
}
public void testArrayOfStringsSerialization() { public void testArrayOfStringsSerialization() {
String[] target = {"Hello", "World"}; String[] target = {"Hello", "World"};