Vojtěch Vojtěch - 11 months ago 52
Java Question

Make Gson to parse integers and not as floats

I am trying to make

to parse values without floating point as Longs and not as Doubles as it defaultly does:

Gson gson = new GsonBuilder()
.registerTypeAdapter(Object.class, (JsonDeserializer<Object>) (json, type, context) -> {
// we don't want integer values to be parsed as floats
String value = json.getAsJsonPrimitive().getAsString();
if (value.matches("\\d+")) {
return Long.valueOf(value);
} else {
return context.deserialize(json, type);

I just want to test, weather the value contains the
and if not, parse it as
. Otherwise use the default parsing method.

However when I put there breakpoints, the method is never called. I suppose I do the registration of the adapter in a wrong way.

EDIT1: The Json might contain lists with strings, integers, doubles and maps. I need a general solution.

EDIT2: I also tried varieties of
with no effect. Still not called.

Answer Source

I couldn't find a better way than to completely override the Gson function. It is quite a hack, but no other solution seem to fix the issue:

public class Gson {

    private static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
        public <T> TypeAdapter<T> create(com.google.gson.Gson gson, TypeToken<T> type) {
            return type.getRawType() == Object.class ? (TypeAdapter<T>) new LongObjectTypeAdapter(gson) : null;

    static {
        try {
            Field field = ObjectTypeAdapter.class.getDeclaredField("FACTORY");

            Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

            field.set(null, FACTORY);

        } catch (Exception e) {
            throw new IllegalStateException(e);

    private com.google.gson.Gson gson = new com.google.gson.Gson();

    public <T> T fromJson(String payload, Class<T> c) {
        return gson.fromJson(payload, c);

    public String toJson(Object object) {
        return gson.toJson(object);

    public static class LongObjectTypeAdapter extends TypeAdapter<Object> {

        private com.google.gson.Gson gson;

        public LongObjectTypeAdapter(com.google.gson.Gson gson) {
            this.gson = gson;

        public Object read(JsonReader in) throws IOException {
            JsonToken token = in.peek();

            switch (token) {
                case BEGIN_ARRAY:
                    ArrayList list = new ArrayList();

                    while(in.hasNext()) {

                    return list;
                case BEGIN_OBJECT:
                    LinkedTreeMap map = new LinkedTreeMap();

                    while(in.hasNext()) {
                        map.put(in.nextName(), this.read(in));

                    return map;
                case STRING:
                    return in.nextString();
                case NUMBER:
                    String value = in.nextString();
                    if (value.contains(".")) {
                        return Double.valueOf(value);
                    } else {
                        return Long.valueOf(value);

                case BOOLEAN:
                    return Boolean.valueOf(in.nextBoolean());
                case NULL:
                    return null;
                    throw new IllegalStateException();

        public void write(JsonWriter out, Object value) throws IOException {
            if (value == null) {
            } else {
                TypeAdapter typeAdapter = gson.getAdapter(value.getClass());
                if (typeAdapter instanceof LongObjectTypeAdapter) {
                } else {
                    typeAdapter.write(out, value);