Implemented support for serializing objects of type Bar<Foo> without the need to specify their type explicitly in toJson method.

This commit is contained in:
Inderjeet Singh 2011-06-25 20:04:14 +00:00
parent ef2f73180b
commit d347128e6f
2 changed files with 21 additions and 8 deletions

View File

@ -18,6 +18,7 @@ package com.google.gson;
import java.lang.reflect.AccessibleObject; import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -59,7 +60,7 @@ final class ReflectingFieldNavigator {
|| exclusionStrategy.shouldSkipClass(fieldAttributes.getDeclaredClass())) { || exclusionStrategy.shouldSkipClass(fieldAttributes.getDeclaredClass())) {
continue; // skip continue; // skip
} }
Type resolvedTypeOfField = fieldAttributes.getResolvedType(); Type resolvedTypeOfField = getMoreSpecificType(fieldAttributes.getResolvedType(), obj, fieldAttributes);
boolean visitedWithCustomHandler = boolean visitedWithCustomHandler =
visitor.visitFieldUsingCustomHandler(fieldAttributes, resolvedTypeOfField, obj); visitor.visitFieldUsingCustomHandler(fieldAttributes, resolvedTypeOfField, obj);
if (!visitedWithCustomHandler) { if (!visitedWithCustomHandler) {
@ -72,6 +73,20 @@ final class ReflectingFieldNavigator {
} }
} }
@SuppressWarnings("unchecked")
private Type getMoreSpecificType(Type type, Object obj, FieldAttributes fieldAttributes) {
try {
if (obj != null && (Object.class == type || type instanceof TypeVariable)) {
Object fieldValue = fieldAttributes.get(obj);
if (fieldValue != null) {
type = fieldValue.getClass();
}
}
} catch (IllegalAccessException e) {
}
return type;
}
private List<FieldAttributes> getAllFields(Type type, Type declaredType) { private List<FieldAttributes> getAllFields(Type type, Type declaredType) {
List<FieldAttributes> fields = fieldsCache.getElement(type); List<FieldAttributes> fields = fieldsCache.getElement(type);
if (fields == null) { if (fields == null) {

View File

@ -18,7 +18,6 @@ package com.google.gson.functional;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase; import junit.framework.TestCase;
import com.google.gson.Gson; import com.google.gson.Gson;
@ -54,12 +53,11 @@ public class RawSerializationTest extends TestCase {
public void testParameterizedObject() { public void testParameterizedObject() {
Bar<Foo> bar = new Bar<Foo>(new Foo(1)); Bar<Foo> bar = new Bar<Foo>(new Foo(1));
String expectedJson = "{\"t\":{\"b\":1}}"; String expectedJson = "{\"t\":{\"b\":1}}";
try { // Ensure that serialization works without specifying the type explicitly
String json = gson.toJson(bar); String json = gson.toJson(bar);
assertEquals(expectedJson, json); assertEquals(expectedJson, json);
} catch (AssertionFailedError expected) { // Ensure that serialization also works when the type is specified explicitly
} json = gson.toJson(bar, new TypeToken<Bar<Foo>>(){}.getType());
String json = gson.toJson(bar, new TypeToken<Bar<Foo>>(){}.getType());
assertEquals(expectedJson, json); assertEquals(expectedJson, json);
} }