Forbid custom serializers for primitive types (so we can avoid boxing in the reflective and array adapters)
This commit is contained in:
parent
fede584b98
commit
e756608568
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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>() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue
Block a user