为什么在序列化内置类型时会忽略 JsonAdapter 注解?

Why is JsonAdapter annotation ignored when serializing built-in type?

问题

设想以下字段:

@JsonAdapter(CustomTypeAdapter.class)
private int field;

反序列化时,CustomTypeAdapterread方法照常调用,但序列化时, write 方法被完全忽略并且内置类型被写出,因为它通常是这样的。 (如果我使用 Integer 而不是 int,也会发生同样的事情。)

问题

我在 the documentation 中找不到任何表明这是预期行为的内容。是吗?或者这是一个错误?

解决方法

我能找到的唯一解决方法是创建自定义 "holder" 类型,然后公开它,例如,

@JsonAdapter(CustomTypeAdapter.class)
class CustomType { /* blah blah */ }

private CustomType field;

public int getField() {
    return field.getValue();
}

public void setField(int field) {
    this.field = new CustomType(field);
}

这可行,但有点麻烦。

虽然我同意它不适用于 int,但我无法在 Gson 中重现它 不适用于 的行为 Integer 2.3.1.首先,你必须使用TypeAdapter<Integer> (or a TypeAdapterFactory) and not JsonSerializer. It specifically says so in the JsonAdapter Javadoc。

The class referenced by this annotation must be either a TypeAdapter or a TypeAdapterFactory. Using the factory interface makes it possible to delegate to the enclosing Gson instance.

那么,类型是不是自动装箱的,所以如果你想使用注释,字段必须是Integer。在玩具示例中结合这两个事实(同样,int 将不起作用),我们有:

import java.io.IOException;

import com.google.gson.Gson;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;

public class JsonAdapterExample {
  public static void main(String[] args) {
    Gson g = new Gson();

    System.out.println(g.toJson(new Car()));
  }

  public static class Car {
    @JsonAdapter(IdAdapter.class)
    Integer id = 10;
  }

  public static class IdAdapter extends TypeAdapter<Integer> {
    @Override
    public Integer read(JsonReader arg0) throws IOException {
      // TODO Auto-generated method stub
      return null;
    }

    @Override
    public void write(JsonWriter arg0, Integer arg1) throws IOException {
      arg0.beginObject();
      arg0.name("id");
      arg0.value(String.valueOf(arg1));
      arg0.endObject();
    } 
  }
}

输出:

{"id":{"id":"10"}}

如果它不起作用,那将是 10 而不是 "10",并且没有内部对象。