當(dāng)我們用Object或者M(jìn)ap中的泛型使用了Object,我們將json轉(zhuǎn)換之后,發(fā)現(xiàn)數(shù)據(jù)中的所以數(shù)值都變成了double類型,0變?yōu)榱?.0,導(dǎo)致后續(xù)程序可能出現(xiàn)一些問(wèn)題。
查看Gson的源碼, 會(huì)發(fā)現(xiàn)Object最后默認(rèn)的TypeAdapter使用的是com.google.gson.internal.bind包下的ObjectTypeAdapter,里邊的處理如下:
/**
* Adapts types whose static type is only 'Object'. Uses getClass() on
* serialization and a primitive/Map/List on deserialization.
*/
public final class ObjectTypeAdapter extends TypeAdapter<Object> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
@SuppressWarnings("unchecked")
@Override public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
if (type.getRawType() == Object.class) {
return (TypeAdapter<T>) new ObjectTypeAdapter(gson);
}
return null;
}
};
private final Gson gson;
ObjectTypeAdapter(Gson gson) {
this.gson = gson;
}
@Override public Object read(JsonReader in) throws IOException {
JsonToken token = in.peek();
switch (token) {
case BEGIN_ARRAY:
List<Object> list = new ArrayList<Object>();
in.beginArray();
while (in.hasNext()) {
list.add(read(in));
}
in.endArray();
return list;
case BEGIN_OBJECT:
Map<String, Object> map = new LinkedTreeMap<String, Object>();
in.beginObject();
while (in.hasNext()) {
map.put(in.nextName(), read(in));
}
in.endObject();
return map;
case STRING:
return in.nextString();
case NUMBER:
return in.nextDouble();
case BOOLEAN:
return in.nextBoolean();
case NULL:
in.nextNull();
return null;
default:
throw new IllegalStateException();
}
}
@SuppressWarnings("unchecked")
@Override public void write(JsonWriter out, Object value) throws IOException {
if (value == null) {
out.nullValue();
return;
}
TypeAdapter<Object> typeAdapter = (TypeAdapter<Object>) gson.getAdapter(value.getClass());
if (typeAdapter instanceof ObjectTypeAdapter) {
out.beginObject();
out.endObject();
return;
}
typeAdapter.write(out, value);
}
}
查看read方法發(fā)現(xiàn)所有的Number類型都被轉(zhuǎn)成了double類型,想要修改掉這個(gè)問(wèn)題,需要自己實(shí)現(xiàn)一個(gè)TypeAdapter,處理Number類型的問(wèn)題,自己重寫(xiě)TypeAdapter,代碼如下:
public class DataTypeAdapter extends TypeAdapter<Object> {
private final TypeAdapter<Object> delegate = new Gson().getAdapter(Object.class);
@Override
public Object read(JsonReader in) throws IOException {
JsonToken token = in.peek();
switch (token) {
case BEGIN_ARRAY:
List<Object> list = new ArrayList<>();
in.beginArray();
while (in.hasNext()) {
list.add(read(in));
}
in.endArray();
return list;
case BEGIN_OBJECT:
Map<String, Object> map = new LinkedTreeMap<>();
in.beginObject();
while (in.hasNext()) {
map.put(in.nextName(), read(in));
}
in.endObject();
return map;
case STRING:
return in.nextString();
case NUMBER:
/**
* 改寫(xiě)數(shù)字的處理邏輯,將數(shù)字值分為整型與浮點(diǎn)型。
*/
double dbNum = in.nextDouble();
// 數(shù)字超過(guò)long的最大值,返回浮點(diǎn)類型
if (dbNum > Long.MAX_VALUE) {
return dbNum;
}
// 判斷數(shù)字是否為整數(shù)值
long lngNum = (long) dbNum;
if (dbNum == lngNum) {
try {
return (int) lngNum;
} catch (Exception e) {
return lngNum;
}
} else {
return dbNum;
}
case BOOLEAN:
return in.nextBoolean();
case NULL:
in.nextNull();
return null;
default:
throw new IllegalStateException();
}
}
@Override
public void write(JsonWriter out, Object value) throws IOException {
delegate.write(out, value);
}
}
經(jīng)過(guò)自己的處理將number類型都進(jìn)行了轉(zhuǎn)換,分別轉(zhuǎn)為int、long和double,這樣就可以解決int轉(zhuǎn)為double的問(wèn)題。
之后將自己重寫(xiě)的TypeAdapter注冊(cè)一下
new GsonBuilder().registerTypeAdapter(new TypeToken<Map<String,Object>>(){}.getType(),new DataTypeAdapter()).create();
這樣使用返回的Gson對(duì)象進(jìn)行轉(zhuǎn)換就不會(huì)出現(xiàn)上述的問(wèn)題。