Forbid custom serializers for primitive types (so we can avoid boxing in the reflective and array adapters)

This commit is contained in:
Jesse Wilson 2011-09-09 06:26:21 +00:00
parent fede584b98
commit e756608568
5 changed files with 88 additions and 139 deletions

View File

@ -31,3 +31,9 @@ com.google.gson.functional.PrimitiveTest.testDeserializingBigIntegerAsLong
GSON 1.x uses arbitrary precision for primitive type conversion (so -122.08e-2132 != 0)
GSON 2.x uses double precision (so -122.08e-2132 == 0)
com.google.gson.functional.PrimitiveTest.testDeserializingBigDecimalAsLongFails
GSON 1.x supports type adapters for primitive types
GSON 2.x doesn't
com.google.gson.functional.CustomTypeAdaptersTest.testCustomSerializerForLong
com.google.gson.functional.CustomTypeAdaptersTest.testCustomDeserializerForLong

View File

@ -18,7 +18,6 @@ package com.google.gson;
import com.google.gson.DefaultTypeAdapters.DefaultDateTypeAdapter;
import com.google.gson.internal.$Gson$Preconditions;
import java.lang.reflect.Type;
import java.sql.Timestamp;
import java.text.DateFormat;
@ -495,6 +494,10 @@ public final class GsonBuilder {
private GsonBuilder registerTypeAdapter(Type type, Object typeAdapter, boolean isSystem) {
$Gson$Preconditions.checkArgument(typeAdapter instanceof JsonSerializer<?>
|| typeAdapter instanceof JsonDeserializer<?> || typeAdapter instanceof InstanceCreator<?>);
if (Primitives.isPrimitive(type) || Primitives.isWrapperType(type)) {
throw new IllegalArgumentException(
"Cannot register type adapters for " + type);
}
if (typeAdapter instanceof InstanceCreator<?>) {
registerInstanceCreator(type, (InstanceCreator<?>) typeAdapter, isSystem);
}

View File

@ -17,13 +17,12 @@
package com.google.gson;
import com.google.gson.internal.$Gson$Preconditions;
import java.lang.reflect.Type;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import com.google.gson.internal.$Gson$Preconditions;
/**
* Contains static utility methods pertaining to primitive types and their
* corresponding wrapper types.
@ -78,7 +77,7 @@ final class Primitives {
*
* @see Class#isPrimitive
*/
public static boolean isWrapperType(Class<?> type) {
public static boolean isWrapperType(Type type) {
return WRAPPER_TO_PRIMITIVE_TYPE.containsKey(
$Gson$Preconditions.checkNotNull(type));
}

View File

@ -173,34 +173,6 @@ public class CustomDeserializerTest extends TestCase {
assertNull(target.base);
}
public void testCustomDeserializerReturnsNullForTopLevelPrimitives() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(long.class, new JsonDeserializer<Long>() {
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return null;
}
}).create();
String json = "10";
assertNull(gson.fromJson(json, long.class));
}
public void testCustomDeserializerReturnsNullForPrimitiveFields() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(long.class, new JsonDeserializer<Long>() {
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return null;
}
}).create();
String json = "{field:10}";
ClassWithLong target = gson.fromJson(json, ClassWithLong.class);
assertEquals(0, target.field);
}
private static class ClassWithLong {
long field;
}
public void testCustomDeserializerReturnsNullForArrayElements() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Base.class, new JsonDeserializer<Base>() {

View File

@ -203,59 +203,28 @@ public class CustomTypeAdaptersTest extends TestCase {
}
}
public void testCustomSerializerForLong() {
final ClassWithBooleanField customSerializerInvoked = new ClassWithBooleanField();
customSerializerInvoked.value = false;
Gson gson = new GsonBuilder().registerTypeAdapter(Long.class, new JsonSerializer<Long>() {
public JsonElement serialize(Long src, Type typeOfSrc, JsonSerializationContext context) {
customSerializerInvoked.value = true;
return new JsonPrimitive(src);
public void testCustomSerializerForbiddenForPrimitives() {
try {
new GsonBuilder().registerTypeAdapter(long.class, new JsonSerializer<Long>() {
public JsonElement serialize(Long s, Type t, JsonSerializationContext c) {
throw new AssertionError();
}
});
fail();
} catch (IllegalArgumentException expected) {
}
}).serializeNulls().create();
ClassWithWrapperLongField src = new ClassWithWrapperLongField();
String json = gson.toJson(src);
assertTrue(json.contains("\"value\":null"));
assertFalse(customSerializerInvoked.value);
customSerializerInvoked.value = false;
src.value = 10L;
json = gson.toJson(src);
assertTrue(json.contains("\"value\":10"));
assertTrue(customSerializerInvoked.value);
}
public void testCustomDeserializerForLong() {
final ClassWithBooleanField customDeserializerInvoked = new ClassWithBooleanField();
customDeserializerInvoked.value = false;
Gson gson = new GsonBuilder().registerTypeAdapter(Long.class, new JsonDeserializer<Long>() {
public Long deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
customDeserializerInvoked.value = true;
if (json == null || json.isJsonNull()) {
return null;
public void testCustomDeserializerForbiddenForPrimitives() {
try {
new GsonBuilder().registerTypeAdapter(long.class, new JsonDeserializer<Long>() {
public Long deserialize(JsonElement json, Type t, JsonDeserializationContext c) {
throw new AssertionError();
}
Number number = json.getAsJsonPrimitive().getAsNumber();
return number == null ? null : number.longValue();
});
fail();
} catch (Exception expected) {
}
}).create();
String json = "{'value':null}";
ClassWithWrapperLongField target = gson.fromJson(json, ClassWithWrapperLongField.class);
assertNull(target.value);
assertFalse(customDeserializerInvoked.value);
customDeserializerInvoked.value = false;
json = "{'value':10}";
target = gson.fromJson(json, ClassWithWrapperLongField.class);
assertEquals(10L, target.value.longValue());
assertTrue(customDeserializerInvoked.value);
}
private static class ClassWithWrapperLongField {
Long value;
}
private static class ClassWithBooleanField {
Boolean value;
}
public void testCustomByteArraySerializer() {