fastjson深度原始碼解析- 序列化(五)
阿新 • • 發佈:2019-02-14
序列化回撥介面實現分析
內部註冊的序列化
fastjson針對常用的型別已經註冊了序列化實現方案:
註冊的型別 | 序列化例項 | 是否支援序列化 | 是否支援反序列化 |
---|---|---|---|
Boolean | BooleanCodec | 是 | 是 |
Character | CharacterCodec | 是 | 是 |
Byte | IntegerCodec | 是 | 是 |
Short | IntegerCodec | 是 | 是 |
Integer | IntegerCodec | 是 | 是 |
Long | LongCodec | 是 | 是 |
Float | FloatCodec | 是 | 是 |
Double | DoubleSerializer | 是 | - |
BigDecimal | BigDecimalCodec | 是 | 是 |
BigInteger | BigIntegerCodec | 是 | 是 |
String | StringCodec | 是 | 是 |
byte[] | PrimitiveArraySerializer | 是 | - |
short[] | PrimitiveArraySerializer | 是 | - |
int[] | PrimitiveArraySerializer | 是 | - |
long[] | PrimitiveArraySerializer | 是 | - |
float[] | PrimitiveArraySerializer | 是 | - |
double[] | PrimitiveArraySerializer | 是 | - |
boolean[] | PrimitiveArraySerializer | 是 | - |
char[] | PrimitiveArraySerializer | 是 | - |
Object[] | ObjectArrayCodec | 是 | 是 |
Class | MiscCodec | 是 | 是 |
SimpleDateFormat | MiscCodec | 是 | 是 |
Currency | MiscCodec | 是 | 是 |
TimeZone | MiscCodec | 是 | 是 |
InetAddress | MiscCodec | 是 | 是 |
Inet4Address | MiscCodec | 是 | 是 |
Inet6Address | MiscCodec | 是 | 是 |
InetSocketAddress | MiscCodec | 是 | 是 |
File | MiscCodec | 是 | 是 |
Appendable | AppendableSerializer | 是 | - |
StringBuffer | AppendableSerializer | 是 | - |
StringBuilder | AppendableSerializer | 是 | - |
Charset | ToStringSerializer | 是 | - |
Pattern | ToStringSerializer | 是 | - |
Locale | ToStringSerializer | 是 | - |
URI | ToStringSerializer | 是 | - |
URL | ToStringSerializer | 是 | - |
UUID | ToStringSerializer | 是 | - |
AtomicBoolean | AtomicCodec | 是 | 是 |
AtomicInteger | AtomicCodec | 是 | 是 |
AtomicLong | AtomicCodec | 是 | 是 |
AtomicReference | ReferenceCodec | 是 | 是 |
AtomicIntegerArray | AtomicCodec | 是 | 是 |
AtomicLongArray | AtomicCodec | 是 | 是 |
WeakReference | ReferenceCodec | 是 | 是 |
SoftReference | ReferenceCodec | 是 | 是 |
LinkedList | CollectionCodec | 是 | 是 |
BooleanCodec序列化
其實理解了前面分析SerializeWriter
, 接下來的內容比較容易理解, BooleanCodec
序列化實現 :
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;
/** 當前object是boolean值, 如果為null,
* 並且序列化開啟WriteNullBooleanAsFalse特性, 輸出false
*/
Boolean value = (Boolean) object;
if (value == null) {
out.writeNull(SerializerFeature.WriteNullBooleanAsFalse);
return;
}
if (value.booleanValue()) {
out.write("true");
} else {
out.write("false");
}
}
BooleanCodec
序列化實現主要判斷是否開啟如果為null值是否輸出false,否則輸出boolean字面量值。
CharacterCodec序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;
Character value = (Character) object;
if (value == null) {
/** 字串為空,輸出空字串 */
out.writeString("");
return;
}
char c = value.charValue();
if (c == 0) {
/** 空白字元,輸出unicode空格字元 */
out.writeString("\u0000");
} else {
/** 輸出字串值 */
out.writeString(value.toString());
}
}
IntegerCodec序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;
Number value = (Number) object;
/** 當前object是整形值, 如果為null,
* 並且序列化開啟WriteNullNumberAsZero特性, 輸出0
*/
if (value == null) {
out.writeNull(SerializerFeature.WriteNullNumberAsZero);
return;
}
/** 判斷整形或者長整型,直接輸出 */
if (object instanceof Long) {
out.writeLong(value.longValue());
} else {
out.writeInt(value.intValue());
}
/** 如果開啟WriteClassName特性,輸出具體值型別 */
if (out.isEnabled(SerializerFeature.WriteClassName)) {
Class<?> clazz = value.getClass();
if (clazz == Byte.class) {
out.write('B');
} else if (clazz == Short.class) {
out.write('S');
}
}
}
LongCodec序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;
/** 當前object是長整形值, 如果為null,
* 並且序列化開啟WriteNullNumberAsZero特性, 輸出0
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullNumberAsZero);
} else {
long value = ((Long) object).longValue();
out.writeLong(value);
/** 如果長整型值範圍和整型相同,顯示新增L 標識為long */
if (out.isEnabled(SerializerFeature.WriteClassName)
&& value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE
&& fieldType != Long.class
&& fieldType != long.class) {
out.write('L');
}
}
}
Long
型別序列化會特殊標識值落在整數範圍內,如果開啟WriteClassName
序列化特性,會追加L字元。
FloatCodec序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;
/** 當前object是float值, 如果為null,
* 並且序列化開啟WriteNullNumberAsZero特性, 輸出0
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullNumberAsZero);
return;
}
float floatValue = ((Float) object).floatValue();
if (decimalFormat != null) {
/** 轉換一下浮點數值格式 */
String floatText = decimalFormat.format(floatValue);
out.write(floatText);
} else {
out.writeFloat(floatValue, true);
}
}
BigDecimalCodec序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;
/** 當前object是BigDecimal值, 如果為null,
* 並且序列化開啟WriteNullNumberAsZero特性, 輸出0
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullNumberAsZero);
} else {
BigDecimal val = (BigDecimal) object;
String outText;
/** 如果序列化開啟WriteBigDecimalAsPlain特性,搞定度輸出不會包含指數e */
if (out.isEnabled(SerializerFeature.WriteBigDecimalAsPlain)) {
outText = val.toPlainString();
} else {
outText = val.toString();
}
out.write(outText);
if (out.isEnabled(SerializerFeature.WriteClassName) && fieldType != BigDecimal.class && val.scale() == 0) {
out.write('.');
}
}
}
BigIntegerCodec序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;
/** 當前object是BigInteger值, 如果為null,
* 並且序列化開啟WriteNullNumberAsZero特性, 輸出0
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullNumberAsZero);
return;
}
BigInteger val = (BigInteger) object;
out.write(val.toString());
}
StringCodec序列化
public void write(JSONSerializer serializer, String value) {
SerializeWriter out = serializer.out;
/** 當前object是string值, 如果為null,
* 並且序列化開啟WriteNullStringAsEmpty特性, 輸出空串""
*/
if (value == null) {
out.writeNull(SerializerFeature.WriteNullStringAsEmpty);
return;
}
out.writeString(value);
}
PrimitiveArraySerializer序列化
public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;
if (object == null) {
/** 當前object是陣列值, 如果為null,
* 並且序列化開啟WriteNullListAsEmpty特性, 輸出空串""
*/
out.writeNull(SerializerFeature.WriteNullListAsEmpty);
return;
}
/** 迴圈寫int陣列 */
if (object instanceof int[]) {
int[] array = (int[]) object;
out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}
out.writeInt(array[i]);
}
out.write(']');
return;
}
/** 迴圈寫short陣列 */
if (object instanceof short[]) {
short[] array = (short[]) object;
out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}
out.writeInt(array[i]);
}
out.write(']');
return;
}
/** 迴圈寫long陣列 */
if (object instanceof long[]) {
long[] array = (long[]) object;
out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}
out.writeLong(array[i]);
}
out.write(']');
return;
}
/** 迴圈寫boolean陣列 */
if (object instanceof boolean[]) {
boolean[] array = (boolean[]) object;
out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}
out.write(array[i]);
}
out.write(']');
return;
}
/** 迴圈寫float陣列 */
if (object instanceof float[]) {
float[] array = (float[]) object;
out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}
float item = array[i];
if (Float.isNaN(item)) {
out.writeNull();
} else {
out.append(Float.toString(item));
}
}
out.write(']');
return;
}
/** 迴圈寫double陣列 */
if (object instanceof double[]) {
double[] array = (double[]) object;
out.write('[');
for (int i = 0; i < array.length; ++i) {
if (i != 0) {
out.write(',');
}
double item = array[i];
if (Double.isNaN(item)) {
out.writeNull();
} else {
out.append(Double.toString(item));
}
}
out.write(']');
return;
}
/** 寫位元組陣列 */
if (object instanceof byte[]) {
byte[] array = (byte[]) object;
out.writeByteArray(array);
return;
}
/** char陣列當做字串 */
char[] chars = (char[]) object;
out.writeString(chars);
}
ObjectArrayCodec序列化
public final void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)
throws IOException {
SerializeWriter out = serializer.out;
Object[] array = (Object[]) object;
/** 當前object是陣列物件, 如果為null,
* 並且序列化開啟WriteNullListAsEmpty特性, 輸出空串[]
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullListAsEmpty);
return;
}
int size = array.length;
int end = size - 1;
/** 當前object是陣列物件, 如果為沒有元素, 輸出空串[] */
if (end == -1) {
out.append("[]");
return;
}
SerialContext context = serializer.context;
serializer.setContext(context, object, fieldName, 0);
try {
Class<?> preClazz = null;
ObjectSerializer preWriter = null;
out.append('[');
/**
* 如果開啟json格式化,迴圈輸出陣列物件,
* 會根據陣列元素class型別查詢序列化例項輸出
*/
if (out.isEnabled(SerializerFeature.PrettyFormat)) {
serializer.incrementIndent();
serializer.println();
for (int i = 0; i < size; ++i) {
if (i != 0) {
out.write(',');
serializer.println();
}
serializer.write(array[i]);
}
serializer.decrementIdent();
serializer.println();
out.write(']');
return;
}
for (int i = 0; i < end; ++i) {
Object item = array[i];
if (item == null) {
out.append("null,");
} else {
if (serializer.containsReference(item)) {
serializer.writeReference(item);
} else {
Class<?> clazz = item.getClass();
/** 如果當前序列化元素和前一次class型別相同,避免再一次class型別查詢序列化例項 */
if (clazz == preClazz) {
preWriter.write(serializer, item, null, null, 0);
} else {
preClazz = clazz;
/** 查詢陣列元素class型別的序列化器 序列化item */
preWriter = serializer.getObjectWriter(clazz);
preWriter.write(serializer, item, null, null, 0);
}
}
out.append(',');
}
}
Object item = array[end];
if (item == null) {
out.append("null]");
} else {
if (serializer.containsReference(item)) {
serializer.writeReference(item);
} else {
serializer.writeWithFieldName(item, end);
}
out.append(']');
}
} finally {
serializer.context = context;
}
}
ObjectArrayCodec
序列化主要判斷是否開啟格式化輸出json,如果是輸出新增適當的縮排。針對陣列元素不一樣會根據元素class型別查詢具體的序列化器輸出,這裡優化了如果元素相同的元素避免冗餘的查詢序列化器。
MiscCodec序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
int features) throws IOException {
SerializeWriter out = serializer.out;
if (object == null) {
out.writeNull();
return;
}
Class<?> objClass = object.getClass();
String strVal;
if (objClass == SimpleDateFormat.class) {
String pattern = ((SimpleDateFormat) object).toPattern();
/** 輸出SimpleDateFormat型別的型別 */
if (out.isEnabled(SerializerFeature.WriteClassName)) {
if (object.getClass() != fieldType) {
out.write('{');
out.writeFieldName(JSON.DEFAULT_TYPE_KEY);
serializer.write(object.getClass().getName());
out.writeFieldValue(',', "val", pattern);
out.write('}');
return;
}
}
/** 轉換SimpleDateFormat物件成pattern字串 */
strVal = pattern;
} else if (objClass == Class.class) {
Class<?> clazz = (Class<?>) object;
/** 轉換Class物件成name字串 */
strVal = clazz.getName();
} else if (objClass == InetSocketAddress.class) {
InetSocketAddress address = (InetSocketAddress) object;
InetAddress inetAddress = address.getAddress();
/** 轉換InetSocketAddress物件成地址和埠字串 */
out.write('{');
if (inetAddress != null) {
out.writeFieldName("address");
serializer.write(inetAddress);
out.write(',');
}
out.writeFieldName("port");
out.writeInt(address.getPort());
out.write('}');
return;
} else if (object instanceof File) {
/** 轉換File物件成檔案路徑字串 */
strVal = ((File) object).getPath();
} else if (object instanceof InetAddress) {
/** 轉換InetAddress物件成主機地址字串 */
strVal = ((InetAddress) object).getHostAddress();
} else if (object instanceof TimeZone) {
TimeZone timeZone = (TimeZone) object;
/** 轉換TimeZone物件成時區id字串 */
strVal = timeZone.getID();
} else if (object instanceof Currency) {
Currency currency = (Currency) object;
/** 轉換Currency物件成幣別編碼字串 */
strVal = currency.getCurrencyCode();
} else if (object instanceof JSONStreamAware) {
JSONStreamAware aware = (JSONStreamAware) object;
aware.writeJSONString(out);
return;
} else if (object instanceof Iterator) {
Iterator<?> it = ((Iterator<?>) object);
/** 迭代器轉換成陣列碼字串 [,,,] */
writeIterator(serializer, out, it);
return;
} else if (object instanceof Iterable) {
/** 迭代器轉換成陣列碼字串 [,,,] */
Iterator<?> it = ((Iterable<?>) object).iterator();
writeIterator(serializer, out, it);
return;
} else if (object instanceof Map.Entry) {
Map.Entry entry = (Map.Entry) object;
Object objKey = entry.getKey();
Object objVal = entry.getValue();
/** 輸出map的Entry值 */
if (objKey instanceof String) {
String key = (String) objKey;
if (objVal instanceof String) {
String value = (String) objVal;
out.writeFieldValueStringWithDoubleQuoteCheck('{', key, value);
} else {
out.write('{');
out.writeFieldName(key);
/** 根據value的class型別查詢序列化器並輸出 */
serializer.write(objVal);
}
} else {
/** 根據key、value的class型別查詢序列化器並輸出 */
out.write('{');
serializer.write(objKey);
out.write(':');
serializer.write(objVal);
}
out.write('}');
return;
} else if (object.getClass().getName().equals("net.sf.json.JSONNull")) {
out.writeNull();
return;
} else {
throw new JSONException("not support class : " + objClass);
}
out.writeString(strVal);
}
MiscCodec
序列化的主要思想是吧JDK內部常用的物件簡化處理,比如TimeZone只保留id輸出,極大地降低了輸出位元組大小。
AppendableSerializer序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
/** 當前object實現了Appendable介面, 如果為null,
* 並且序列化開啟WriteNullStringAsEmpty特性, 輸出空串""
*/
if (object == null) {
SerializeWriter out = serializer.out;
out.writeNull(SerializerFeature.WriteNullStringAsEmpty);
return;
}
/** 輸出物件toString結果作為json串 */
serializer.write(object.toString());
}
ToStringSerializer序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType,
int features) throws IOException {
SerializeWriter out = serializer.out;
/** 如果為null, 輸出空串"null" */
if (object == null) {
out.writeNull();
return;
}
/** 輸出物件toString結果作為json串 */
String strVal = object.toString();
out.writeString(strVal);
}
AtomicCodec序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;
if (object instanceof AtomicInteger) {
AtomicInteger val = (AtomicInteger) object;
/** 獲取整數輸出 */
out.writeInt(val.get());
return;
}
if (object instanceof AtomicLong) {
AtomicLong val = (AtomicLong) object;
/** 獲取長整數輸出 */
out.writeLong(val.get());
return;
}
if (object instanceof AtomicBoolean) {
AtomicBoolean val = (AtomicBoolean) object;
/** 獲取boolean值輸出 */
out.append(val.get() ? "true" : "false");
return;
}
/** 當前object是原子陣列型別, 如果為null,輸出[] */
if (object == null) {
out.writeNull(SerializerFeature.WriteNullListAsEmpty);
return;
}
/** 遍歷AtomicIntegerArray,輸出int陣列型別 */
if (object instanceof AtomicIntegerArray) {
AtomicIntegerArray array = (AtomicIntegerArray) object;
int len = array.length();
out.write('[');
for (int i = 0; i < len; ++i) {
int val = array.get(i);
if (i != 0) {
out.write(',');
}
out.writeInt(val);
}
out.write(']');
return;
}
/** 遍歷AtomicLongArray,輸出long陣列型別 */
AtomicLongArray array = (AtomicLongArray) object;
int len = array.length();
out.write('[');
for (int i = 0; i < len; ++i) {
long val = array.get(i);
if (i != 0) {
out.write(',');
}
out.writeLong(val);
}
out.write(']');
}
ReferenceCodec序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
Object item;
/** 當前object是Reference型別,
* 呼叫get()查詢對應的class序列化器輸出
*/
if (object instanceof AtomicReference) {
AtomicReference val = (AtomicReference) object;
item = val.get();
} else {
item = ((Reference) object).get();
}
serializer.write(item);
}
CollectionCodec序列化
public void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features) throws IOException {
SerializeWriter out = serializer.out;
/** 當前object是集合物件, 如果為null,
* 並且序列化開啟WriteNullListAsEmpty特性, 輸出空串[]
*/
if (object == null) {
out.writeNull(SerializerFeature.WriteNullListAsEmpty);
return;
}
Type elementType = null;
if (out.isEnabled(SerializerFeature.WriteClassName)
|| SerializerFeature.isEnabled(features, SerializerFeature.WriteClassName))
{
/** 獲取欄位泛型型別 */
elementType = TypeUtils.getCollectionItemType(fieldType);
}
Collection<?> collection = (Collection<?>) object;
SerialContext context = serializer.context;
serializer.setContext(context, object, fieldName, 0);
if (out.isEnabled(SerializerFeature.WriteClassName)) {
if (HashSet.class == collection.getClass()) {
out.append("Set");
} else if (TreeSet.class == collection.getClass()) {
out.append("TreeSet");
}
}
try {
int i = 0;
out.append('[');
for (Object item : collection) {
if (i++ != 0) {
out.append(',');
}
if (item == null) {
out.writeNull();
continue;
}
Class<?> clazz = item.getClass();
/** 獲取整形型別值,輸出 */
if (clazz == Integer.class) {
out.writeInt(((Integer) item).intValue());
continue;
}
/** 獲取整形長型別值,輸出並新增L標識(如果開啟WriteClassName特性) */
if (clazz == Long.class) {
out.writeLong(((Long) item).longValue());
if (out.isEnabled(SerializerFeature.WriteClassName)) {
out.write('L');
}
continue;
}
/** 根據集合型別查詢序列化例項處理,JavaBeanSerializer後面單獨分析 */
ObjectSerializer itemSerializer = serializer.getObjectWriter(clazz);
if (SerializerFeature.isEnabled(features, SerializerFeature.WriteClassName)
&& itemSerializer instanceof JavaBeanSerializer) {
JavaBeanSerializer javaBeanSerializer = (JavaBeanSerializer) itemSerializer;
javaBeanSerializer.writeNoneASM(serializer, item, i - 1, elementType, features);
} else {
itemSerializer.write(serializer, item, i - 1, elementType, features);
}
}
out.append(']');
} finally {
serializer.context = context;
}
}