Gson提供了丰富的预定义类型适配器,在对象和JSON串之间进行序列化和反序列化时,指定对象和字符串之间的转换方式,
DateTypeAdapter
public final class DateTypeAdapter extends TypeAdapter<Date> {
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
@SuppressWarnings("unchecked") // we use a runtime check to make sure the 'T's equal
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
return typeToken.getRawType() == Date.class ? (TypeAdapter<T>) new DateTypeAdapter() : null;
}
};
private final DateFormat enUsFormat
= DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.US);//美国Locale
private final DateFormat localFormat
= DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT);//本地Locale
private final DateFormat iso8601Format = buildIso8601Format();//ISO8601时间格式
private static DateFormat buildIso8601Format() {//构造(ISO8601DateFormat
DateFormat iso8601Format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US);
iso8601Format.setTimeZone(TimeZone.getTimeZone("UTC"));
return iso8601Format;
}
@Override public Date read(JsonReader in) throws IOException {//JsonReader中包含着要转换为Date的字符串
if (in.peek() == JsonToken.NULL) {//如果字符串为null
in.nextNull();//将这个null消费完
return null;
}
return deserializeToDate(in.nextString());//将字符串反序列化为日期对象
}
private synchronized Date deserializeToDate(String json) {
try {
return localFormat.parse(json);//首先尝试本地Locale
} catch (ParseException ignored) {
}
try {
return enUsFormat.parse(json);//再次尝试美国英语Locale
} catch (ParseException ignored) {
}
try {
return iso8601Format.parse(json); //最后尝试ISO8601时间格式
} catch (ParseException e) {
throw new JsonSyntaxException(json, e);
}
}
@Override public synchronized void write(JsonWriter out, Date value) throws IOException {
if (value == null) {
out.nullValue();//设置null值
return;
}
String dateFormatAsString = enUsFormat.format(value);//直接使用美国英语Locale将Date转换成为字符串
out.value(dateFormatAsString);
}
}
ArrayTypeAdapter
public final class ArrayTypeAdapter<E> extends TypeAdapter<Object> {//为什么是Object而不是E
public static final TypeAdapterFactory FACTORY = new TypeAdapterFactory() {
@SuppressWarnings({"unchecked", "rawtypes"})
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> typeToken) {
Type type = typeToken.getType();
//如果type不是Array,返回null
if (!(type instanceof GenericArrayType || type instanceof Clas