fastjson源码简单分析

相信每个开发人员都用过json吧。然而在json常用的工具中鼎鼎有名的无非是fastjson和gson了,但是不知道小伙伴没有没有去了解过他们其中的源码设计?我们接下来重点看一下fastjson的toJSONString方法。

我们拿Student(String studentId,String studentName,Byte studentAge,Boolean studentSex)来做例子

            byte age = 20;
            Student student = new Student("0001","张三",age,true);
            String s = JSONObject.toJSONString(student);
            logger.info("s==={}",s);

我们直接跟进去toJSONString方法:

    /**
     * This method serializes the specified object into its equivalent Json representation. Note that this method works fine if the any of the object fields are of generic type,
     * just the object itself should not be of a generic type. If you want to write out the object to a
     * {@link Writer}, use {@link #writeJSONString(Writer, Object, SerializerFeature[])} instead.
     *
     * @param object the object for which json representation is to be created setting for fastjson
     * @return Json representation of {@code object}.
     */
    public static String toJSONString(Object object) {
        return toJSONString(object, emptyFilters);
    }

    public static String toJSONString(Object object, SerializeFilter[] filters, SerializerFeature... features) {
        return toJSONString(object, SerializeConfig.globalInstance, filters, null, DEFAULT_GENERATE_FEATURE, features);
    }

    //这里是我们的重点方法
    /**
     * @since 1.2.9
     * @return
     */
    public static String toJSONString(Object object, // 
                                      SerializeConfig config, // 
                                      SerializeFilter[] filters, // 
                                      String dateFormat, //
                                      int defaultFeatures, // 
                                      SerializerFeature... features) {
        SerializeWriter out = new SerializeWriter(null, defaultFeatures, features);

        try {
            JSONSerializer serializer = new JSONSerializer(out, config);
            
            if (dateFormat != null && dateFormat.length() != 0) {
                serializer.setDateFormat(dateFormat);
                serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
            }

            if (filters != null) {
                for (SerializeFilter filter : filters) {
                    serializer.addFilter(filter);
                }
            }

            serializer.write(object);

            return out.toString();
        } finally {
            out.close();
        }
    }

我们看方法中的最后一行return out.toString();说明我们最终的转成的json字符串是写到out中去的,那么我们的重点对象就是这个out了也就是SerializeWriter了。

out.toString()方法:我们可以看到SerializeWriter中维护了一个字符数组buf[]来写入数据的。

    private final static Charset   UTF8                            = Charset.forName("UTF-8");

    private final static ThreadLocal         bufLocal      = new ThreadLocal();
    private final static ThreadLocal         bytesBufLocal = new ThreadLocal();

    protected char                                          buf[];

    /**
     * The number of chars in the buffer.
     */
    protected int                                           count;

    
    
    public String toString() {
        return new String(buf, 0, count);
    }

那是如何写入到out对象中的buf呢?那就还得回去看我们的toJSONString方法了,我们可以看到serializer.write(object)这行,这个是写入out的方法,但是在写入对象之前,serializer进行了初始化并设置了一些参数:

        JSONSerializer serializer = new JSONSerializer(out, config);
            
            if (dateFormat != null && dateFormat.length() != 0) {
                serializer.setDateFormat(dateFormat);
                serializer.config(SerializerFeature.WriteDateUseDateFormat, true);
            }

            if (filters != null) {
                for (SerializeFilter filter : filters) {
                    serializer.addFilter(filter);
                }
            }

            serializer.write(object);

JSONSerializer serializer = new JSONSerializer(out,config);这行代码说明了,serilaizer对象中维护着out和config两个东西,out就是我们刚才说的out了,而config是什么东西呢?部分代码如下:

我们可以看到该类维护一个主要的map对象IdentityHashMap serializers,该对象初始化时往map中放了一堆的key为class,value为ObjectSerializer的东西,暂时先不管,知道里面放的什么就行了。

 * circular references detect
 * 
 * @author wenshao[[email protected]]
 */
public class SerializeConfig {

    public final static SerializeConfig                   globalInstance  = new SerializeConfig();

    private static boolean                                awtError        = false;
    private static boolean                                jdk8Error       = false;
    private static boolean                                oracleJdbcError = false;
    private static boolean                                springfoxError  = false;
    private static boolean                                guavaError      = false;

    private boolean                                       asm             = !ASMUtils.IS_ANDROID;
    private ASMSerializerFactory                          asmFactory;
    protected String                                      typeKey         = JSON.DEFAULT_TYPE_KEY;
    public PropertyNamingStrategy                         propertyNamingStrategy;

    private final IdentityHashMap serializers;



    public SerializeConfig() {
		this(1024);
	}

	public SerializeConfig(int tableSize) {
	    serializers = new IdentityHashMap(1024);
		
		try {
		    if (asm) {
		        asmFactory = new ASMSerializerFactory();
		    }
		} catch (Throwable eror) {
		    asm = false;
//		} catch (ExceptionInInitializerError error) {
//		    asm = false;
		}

		put(Boolean.class, BooleanCodec.instance);
		put(Character.class, CharacterCodec.instance);
		put(Byte.class, IntegerCodec.instance);
		put(Short.class, IntegerCodec.instance);
		put(Integer.class, IntegerCodec.instance);
		put(Long.class, LongCodec.instance);
		put(Float.class, FloatCodec.instance);
		put(Double.class, DoubleSerializer.instance);
		put(BigDecimal.class, BigDecimalCodec.instance);
		put(BigInteger.class, BigIntegerCodec.instance);
		put(String.class, StringCodec.instance);
		put(byte[].class, PrimitiveArraySerializer.instance);
		put(short[].class, PrimitiveArraySerializer.instance);
		put(int[].class, PrimitiveArraySerializer.instance);
		put(long[].class, PrimitiveArraySerializer.instance);
		put(float[].class, PrimitiveArraySerializer.instance);
		put(double[].class, PrimitiveArraySerializer.instance);
		put(boolean[].class, PrimitiveArraySerializer.instance);
		put(char[].class, PrimitiveArraySerializer.instance);
		put(Object[].class, ObjectArrayCodec.instance);
		put(Class.class, MiscCodec.instance);

		put(SimpleDateFormat.class, MiscCodec.instance);
		put(Currency.class, new MiscCodec());
		put(TimeZone.class, MiscCodec.instance);
		put(InetAddress.class, MiscCodec.instance);
		put(Inet4Address.class, MiscCodec.instance);
		put(Inet6Address.class, MiscCodec.instance);
		put(InetSocketAddress.class, MiscCodec.instance);
		put(File.class, MiscCodec.instance);
		put(Appendable.class, AppendableSerializer.instance);
		put(StringBuffer.class, AppendableSerializer.instance);
		put(StringBuilder.class, AppendableSerializer.instance);
		put(Charset.class, ToStringSerializer.instance);
		put(Pattern.class, ToStringSerializer.instance);
		put(Locale.class, ToStringSerializer.instance);
		put(URI.class, ToStringSerializer.instance);
		put(URL.class, ToStringSerializer.instance);
		put(UUID.class, ToStringSerializer.instance);

		// atomic
		put(AtomicBoolean.class, AtomicCodec.instance);
		put(AtomicInteger.class, AtomicCodec.instance);
		put(AtomicLong.class, AtomicCodec.instance);
		put(AtomicReference.class, ReferenceCodec.instance);
		put(AtomicIntegerArray.class, AtomicCodec.instance);
		put(AtomicLongArray.class, AtomicCodec.instance);
		
		put(WeakReference.class, ReferenceCodec.instance);
		put(SoftReference.class, ReferenceCodec.instance);
	}

我们知道了serializer里面放了out和config就够了,接下来看我们serializer.writer(object);方法是如何执行的:

看的第一眼是不是觉得,怎么可以这么简单(哈哈~我第一样反正是这样认为的)。

    public final void write(Object object) {
        if (object == null) {
            out.writeNull();
            return;
        }

        Class clazz = object.getClass();
        ObjectSerializer writer = getObjectWriter(clazz);

        try {
            writer.write(this, object, null, null, 0);
        } catch (IOException e) {
            throw new JSONException(e.getMessage(), e);
        }
    }

我们一行一行来看。我的习惯是先看最后一行也就是return行,此方法没有return那我们就看最后一行,writer.writer(this,object,null,null,0);当我们跟进去看源码时发现是个接口,没有具体的方法实现,所以我们现在要找出的是writer这个对象具体是哪个类中的write方法(这是我们的重点看的地方),然后我们接着看,if语句不用看我传的obj不可能为null的,所以就剩两行了,准确的说是一行:ObjectSerializer writer = getObjectWriter(clazz);我们继续:

    public ObjectSerializer getObjectWriter(Class clazz) {
        return config.getObjectWriter(clazz);
    }

咦~,这个config有没有很熟悉啊,就是我们刚才维护map的那个config,这行的代码就是从map里获取一个serializer,我们可以回过头看一下刚才config初始化时放了什么,都是一些java原始的类对应的serializer,并没有我们clazz对应的value值,获取的应该是null啊,别着急,我们继续看config.getObjectWriter(clazz);

哇,是真的长,但是关键的就那几步:

    public ObjectSerializer getObjectWriter(Class clazz) {
        return getObjectWriter(clazz, true);
    }
	
	private ObjectSerializer getObjectWriter(Class clazz, boolean create) {
        ObjectSerializer writer = serializers.get(clazz);

        if (writer == null) {
            try {
                final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
                for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) {
                    if (!(o instanceof AutowiredObjectSerializer)) {
                        continue;
                    }

                    AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o;
                    for (Type forType : autowired.getAutowiredFor()) {
                        put(forType, autowired);
                    }
                }
            } catch (ClassCastException ex) {
                // skip
            }

            writer = serializers.get(clazz);
        }

        if (writer == null) {
            final ClassLoader classLoader = JSON.class.getClassLoader();
            if (classLoader != Thread.currentThread().getContextClassLoader()) {
                try {
                    for (Object o : ServiceLoader.load(AutowiredObjectSerializer.class, classLoader)) {

                        if (!(o instanceof AutowiredObjectSerializer)) {
                            continue;
                        }

                        AutowiredObjectSerializer autowired = (AutowiredObjectSerializer) o;
                        for (Type forType : autowired.getAutowiredFor()) {
                            put(forType, autowired);
                        }
                    }
                } catch (ClassCastException ex) {
                    // skip
                }

                writer = serializers.get(clazz);
            }
        }
        
        if (writer == null) {
            if (Map.class.isAssignableFrom(clazz)) {
                put(clazz, MapSerializer.instance);
            } else if (List.class.isAssignableFrom(clazz)) {
                put(clazz, ListSerializer.instance);
            } else if (Collection.class.isAssignableFrom(clazz)) {
                put(clazz, CollectionCodec.instance);
            } else if (Date.class.isAssignableFrom(clazz)) {
                put(clazz, DateCodec.instance);
            } else if (JSONAware.class.isAssignableFrom(clazz)) {
                put(clazz, JSONAwareSerializer.instance);
            } else if (JSONSerializable.class.isAssignableFrom(clazz)) {
                put(clazz, JSONSerializableSerializer.instance);
            } else if (JSONStreamAware.class.isAssignableFrom(clazz)) {
                put(clazz, MiscCodec.instance);
            } else if (clazz.isEnum() || (clazz.getSuperclass() != null && clazz.getSuperclass().isEnum())) {
                JSONType jsonType = clazz.getAnnotation(JSONType.class);
                if (jsonType != null && jsonType.serializeEnumAsJavaBean()) {
                    put(clazz, createJavaBeanSerializer(clazz));
                } else {
                    put(clazz, EnumSerializer.instance);
                }
            } else if (clazz.isArray()) {
                Class componentType = clazz.getComponentType();
                ObjectSerializer compObjectSerializer = getObjectWriter(componentType);
                put(clazz, new ArraySerializer(componentType, compObjectSerializer));
            } else if (Throwable.class.isAssignableFrom(clazz)) {
                SerializeBeanInfo beanInfo = TypeUtils.buildBeanInfo(clazz, null, propertyNamingStrategy);
                beanInfo.features |= SerializerFeature.WriteClassName.mask;
                put(clazz, new JavaBeanSerializer(beanInfo));
            } else if (TimeZone.class.isAssignableFrom(clazz) || Map.Entry.class.isAssignableFrom(clazz)) {
                put(clazz, MiscCodec.instance);
            } else if (Appendable.class.isAssignableFrom(clazz)) {
                put(clazz, AppendableSerializer.instance);
            } else if (Charset.class.isAssignableFrom(clazz)) {
                put(clazz, ToStringSerializer.instance);
            } else if (Enumeration.class.isAssignableFrom(clazz)) {
                put(clazz, EnumerationSerializer.instance);
            } else if (Calendar.class.isAssignableFrom(clazz) //
                    || XMLGregorianCalendar.class.isAssignableFrom(clazz)) {
                put(clazz, CalendarCodec.instance);
            } else if (Clob.class.isAssignableFrom(clazz)) {
                put(clazz, ClobSeriliazer.instance);
            } else if (TypeUtils.isPath(clazz)) {
                put(clazz, ToStringSerializer.instance);
            } else if (Iterator.class.isAssignableFrom(clazz)) {
                put(clazz, MiscCodec.instance);
            } else {
                String className = clazz.getName();
                if (className.startsWith("java.awt.") //
                    && AwtCodec.support(clazz) //
                ) {
                    // awt
                    if (!awtError) {
                        try {
                            put(Class.forName("java.awt.Color"), AwtCodec.instance);
                            put(Class.forName("java.awt.Font"), AwtCodec.instance);
                            put(Class.forName("java.awt.Point"), AwtCodec.instance);
                            put(Class.forName("java.awt.Rectangle"), AwtCodec.instance);
                        } catch (Throwable e) {
                            awtError = true;
                            // skip
                        }
                    }
                    return  AwtCodec.instance;
                }
                
                // jdk8
                if ((!jdk8Error) //
                    && (className.startsWith("java.time.") //
                        || className.startsWith("java.util.Optional") //
                        || className.equals("java.util.concurrent.atomic.LongAdder")
                        || className.equals("java.util.concurrent.atomic.DoubleAdder")
                    )) {
                    try {
                        put(Class.forName("java.time.LocalDateTime"), Jdk8DateCodec.instance);
                        put(Class.forName("java.time.LocalDate"), Jdk8DateCodec.instance);
                        put(Class.forName("java.time.LocalTime"), Jdk8DateCodec.instance);
                        put(Class.forName("java.time.ZonedDateTime"), Jdk8DateCodec.instance);
                        put(Class.forName("java.time.OffsetDateTime"), Jdk8DateCodec.instance);
                        put(Class.forName("java.time.OffsetTime"), Jdk8DateCodec.instance);
                        put(Class.forName("java.time.ZoneOffset"), Jdk8DateCodec.instance);
                        put(Class.forName("java.time.ZoneRegion"), Jdk8DateCodec.instance);
                        put(Class.forName("java.time.Period"), Jdk8DateCodec.instance);
                        put(Class.forName("java.time.Duration"), Jdk8DateCodec.instance);
                        put(Class.forName("java.time.Instant"), Jdk8DateCodec.instance);

                        put(Class.forName("java.util.Optional"), OptionalCodec.instance);
                        put(Class.forName("java.util.OptionalDouble"), OptionalCodec.instance);
                        put(Class.forName("java.util.OptionalInt"), OptionalCodec.instance);
                        put(Class.forName("java.util.OptionalLong"), OptionalCodec.instance);

                        put(Class.forName("java.util.concurrent.atomic.LongAdder"), AdderSerializer.instance);
                        put(Class.forName("java.util.concurrent.atomic.DoubleAdder"), AdderSerializer.instance);
                        
                        writer = serializers.get(clazz);
                        if (writer != null) {
                            return writer;
                        }
                    } catch (Throwable e) {
                        // skip
                        jdk8Error = true;
                    }
                }
                
                if ((!oracleJdbcError) //
                    && className.startsWith("oracle.sql.")) {
                    try {
                        put(Class.forName("oracle.sql.DATE"), DateCodec.instance);
                        put(Class.forName("oracle.sql.TIMESTAMP"), DateCodec.instance);
                        
                        writer = serializers.get(clazz);
                        if (writer != null) {
                            return writer;
                        }
                    } catch (Throwable e) {
                        // skip
                        oracleJdbcError = true;
                    }
                }
                
                if ((!springfoxError) //
                    && className.equals("springfox.documentation.spring.web.json.Json")) {
                    try {
                        put(Class.forName("springfox.documentation.spring.web.json.Json"), //
                            SwaggerJsonSerializer.instance);
                        
                        writer = serializers.get(clazz);
                        if (writer != null) {
                            return writer;
                        }
                    } catch (ClassNotFoundException e) {
                        // skip
                        springfoxError = true;
                    }
                }

                if ((!guavaError) //
                        && className.startsWith("com.google.common.collect.")) {
                    try {
                        put(Class.forName("com.google.common.collect.HashMultimap"), //
                                GuavaCodec.instance);
                        put(Class.forName("com.google.common.collect.LinkedListMultimap"), //
                                GuavaCodec.instance);
                        put(Class.forName("com.google.common.collect.ArrayListMultimap"), //
                                GuavaCodec.instance);
                        put(Class.forName("com.google.common.collect.TreeMultimap"), //
                                GuavaCodec.instance);

                        writer = serializers.get(clazz);
                        if (writer != null) {
                            return writer;
                        }
                    } catch (ClassNotFoundException e) {
                        // skip
                        guavaError = true;
                    }
                }

                if (className.equals("net.sf.json.JSONNull")) {
                    try {
                        put(Class.forName("net.sf.json.JSONNull"), //
                                MiscCodec.instance);
                    } catch (ClassNotFoundException e) {
                        // skip
                    }
                    writer = serializers.get(clazz);
                    if (writer != null) {
                        return writer;
                    }
                }

                if (TypeUtils.isProxy(clazz)) {
                    Class superClazz = clazz.getSuperclass();

                    ObjectSerializer superWriter = getObjectWriter(superClazz);
                    put(clazz, superWriter);
                    return superWriter;
                }

                if (create) {
                    put(clazz, createJavaBeanSerializer(clazz));
                }
            }

            writer = serializers.get(clazz);
        }
        return writer;
    }

一:ObjectSerializer writer = serializers.get(clazz);(先从map中取,肯定null的)

二:如果不是null,就去看这个class是不是map、list、array、collection等等,如果是从config中获取对应的serializer,最后发现都不是

fastjson源码简单分析_第1张图片

三:都不是返回什么?你都没有就给你创建一个呗?最后执行到

fastjson源码简单分析_第2张图片

 put方法?,此时才去创建了一个JavaBeanSerializer放到了config中,也就是我们最终拿到那个writer就是createJavaBeanSerializer(clazz);返回的东西,我们不就是找这个吗?果断进去看下返回的JavaBeanSerializer是什么东西,里面的write方法是怎么写如到buff[]里面的。我们把部分代码和write方法摘出来看一下

 /**
 * @author wenshao[[email protected]]
 */
public class JavaBeanSerializer extends SerializeFilterable implements ObjectSerializer {
    // serializers
    protected final FieldSerializer[] getters;
    protected final FieldSerializer[] sortedGetters;
    
    protected SerializeBeanInfo       beanInfo;
    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;
        }

        if (writeReference(serializer, object, features)) {
            return;
        }

        final FieldSerializer[] getters;

        if (out.sortField) {
            getters = this.sortedGetters;
        } else {
            getters = this.getters;
        }

        SerialContext parent = serializer.context;
        serializer.setContext(parent, object, fieldName, this.beanInfo.features, features);

        final boolean writeAsArray = isWriteAsArray(serializer, features);

        try {
            final char startSeperator = writeAsArray ? '[' : '{';
            final char endSeperator = writeAsArray ? ']' : '}';
            out.append(startSeperator);

            if (getters.length > 0 && out.isEnabled(SerializerFeature.PrettyFormat)) {
                serializer.incrementIndent();
                serializer.println();
            }

            boolean commaFlag = false;

            if ((this.beanInfo.features & SerializerFeature.WriteClassName.mask) != 0
                || serializer.isWriteClassName(fieldType, object)) {
                Class objClass = object.getClass();
                if (objClass != fieldType) {
                    writeClassName(serializer, object);
                    commaFlag = true;
                }
            }

            char seperator = commaFlag ? ',' : '\0';

            final boolean directWritePrefix = out.quoteFieldNames && !out.useSingleQuotes;
            char newSeperator = this.writeBefore(serializer, object, seperator);
            commaFlag = newSeperator == ',';

            final boolean skipTransient = out.isEnabled(SerializerFeature.SkipTransientField);
            final boolean ignoreNonFieldGetter = out.isEnabled(SerializerFeature.IgnoreNonFieldGetter);

            for (int i = 0; i < getters.length; ++i) {
                FieldSerializer fieldSerializer = getters[i];

                Field field = fieldSerializer.fieldInfo.field;
                FieldInfo fieldInfo = fieldSerializer.fieldInfo;
                String fieldInfoName = fieldInfo.name;
                Class fieldClass = fieldInfo.fieldClass;

                if (skipTransient) {
                    if (field != null) {
                        if (fieldInfo.fieldTransient) {
                            continue;
                        }
                    }
                }

                if (ignoreNonFieldGetter) {
                    if (field == null) {
                        continue;
                    }
                }

                if ((!this.applyName(serializer, object, fieldInfo.name)) //
                    || !this.applyLabel(serializer, fieldInfo.label)) {
                    continue;
                }


                Object propertyValue;
                
                try {
                    propertyValue = fieldSerializer.getPropertyValueDirect(object);
                } catch (InvocationTargetException ex) {
                    if (out.isEnabled(SerializerFeature.IgnoreErrorGetter)) {
                        propertyValue = null;
                    } else {
                        throw ex;
                    }
                }

                if (!this.apply(serializer, object, fieldInfoName, propertyValue)) {
                    continue;
                }

                String key = fieldInfoName;
                key = this.processKey(serializer, object, key, propertyValue);

                Object originalValue = propertyValue;
                propertyValue = this.processValue(serializer, fieldSerializer.fieldContext, object, fieldInfoName,
                                                        propertyValue);

                if (propertyValue == null && !writeAsArray) {
                    if ((!fieldSerializer.writeNull) && (!out.isEnabled(SerializerFeature.WRITE_MAP_NULL_FEATURES))) {
                        continue;
                    }
                }

                if (propertyValue != null && out.notWriteDefaultValue) {
                    Class fieldCLass = fieldInfo.fieldClass;
                    if (fieldCLass == byte.class && propertyValue instanceof Byte
                        && ((Byte) propertyValue).byteValue() == 0) {
                        continue;
                    } else if (fieldCLass == short.class && propertyValue instanceof Short
                               && ((Short) propertyValue).shortValue() == 0) {
                        continue;
                    } else if (fieldCLass == int.class && propertyValue instanceof Integer
                               && ((Integer) propertyValue).intValue() == 0) {
                        continue;
                    } else if (fieldCLass == long.class && propertyValue instanceof Long
                               && ((Long) propertyValue).longValue() == 0L) {
                        continue;
                    } else if (fieldCLass == float.class && propertyValue instanceof Float
                               && ((Float) propertyValue).floatValue() == 0F) {
                        continue;
                    } else if (fieldCLass == double.class && propertyValue instanceof Double
                               && ((Double) propertyValue).doubleValue() == 0D) {
                        continue;
                    } else if (fieldCLass == boolean.class && propertyValue instanceof Boolean
                               && !((Boolean) propertyValue).booleanValue()) {
                        continue;
                    }
                }

                if (commaFlag) {
                    out.write(',');
                    if (out.isEnabled(SerializerFeature.PrettyFormat)) {
                        serializer.println();
                    }
                }

                if (key != fieldInfoName) {
                    if (!writeAsArray) {
                        out.writeFieldName(key, true);
                    }

                    serializer.write(propertyValue);
                } else if (originalValue != propertyValue) {
                    if (!writeAsArray) {
                        fieldSerializer.writePrefix(serializer);
                    }
                    serializer.write(propertyValue);
                } else {
                    if (!writeAsArray) {
                        if (directWritePrefix) {
                            out.write(fieldInfo.name_chars, 0, fieldInfo.name_chars.length);
                        } else {
                            fieldSerializer.writePrefix(serializer);
                        }
                    }

                    if (!writeAsArray) {
                        JSONField fieldAnnotation = fieldInfo.getAnnotation();
                        if (fieldClass == String.class && (fieldAnnotation == null || fieldAnnotation.serializeUsing() == Void.class)) {
                            if (propertyValue == null) {
                                if ((out.features & SerializerFeature.WriteNullStringAsEmpty.mask) != 0
                                    || (fieldSerializer.features
                                        & SerializerFeature.WriteNullStringAsEmpty.mask) != 0) {
                                    out.writeString("");
                                } else {
                                    out.writeNull();
                                }
                            } else {
                                String propertyValueString = (String) propertyValue;

                                if (out.useSingleQuotes) {
                                    out.writeStringWithSingleQuote(propertyValueString);
                                } else {
                                    out.writeStringWithDoubleQuote(propertyValueString, (char) 0);
                                }
                            }
                        } else {
                            fieldSerializer.writeValue(serializer, propertyValue);
                        }
                    } else {
                        fieldSerializer.writeValue(serializer, propertyValue);
                    }
                }

                commaFlag = true;
            }

            this.writeAfter(serializer, object, commaFlag ? ',' : '\0');

            if (getters.length > 0 && out.isEnabled(SerializerFeature.PrettyFormat)) {
                serializer.decrementIdent();
                serializer.println();
            }

            out.append(endSeperator);
        } catch (Exception e) {
            String errorMessage = "write javaBean error";
            if (object != null) {
                errorMessage += ", class " + object.getClass().getName();
            }
            if (fieldName != null) {
                errorMessage += ", fieldName : " + fieldName;
            }
            if (e.getMessage() != null) {
                errorMessage += (", " + e.getMessage());
            }

            throw new JSONException(errorMessage, e);
        } finally {
            serializer.context = parent;
        }
    }

首先里面有两个数组和一个beanInfo,getters里面放的是obj的变量名称、变量类型、method等信息,最终利用这些拼接起来的写入的out对象里的,beanInfo就是obj类名、class类型等class的属性。

这就是fastjson中toJSONString()方法的大致流程了,不知道小伙伴们了解吗?

你可能感兴趣的:(Java)