Repository: alibaba/fastjson2
Pull request #3513 (2025-04-22 14:40:25)

fix not write default value for primitive types, for issue #3186
### What this PR does / why we need it?

fix not write default value for primitive types, for issue #3186

### Summary of your change



#### Please indicate you've done the following:

- [ ] Made sure tests are passing and test coverage is added if needed.
- [ ] Made sure commit message follow the rule of [Conventional Commits specification](https://www.conventionalcommits.org/).
- [ ] Considered the docs impact and opened a new docs issue or PR with docs changes if needed.



Patch:
diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONWriter.java b/core/src/main/java/com/alibaba/fastjson2/JSONWriter.java
index 942a846e6..92d0ea94d 100644
--- a/core/src/main/java/com/alibaba/fastjson2/JSONWriter.java
+++ b/core/src/main/java/com/alibaba/fastjson2/JSONWriter.java
@@ -1147,6 +1147,18 @@ public abstract class JSONWriter
 
     public abstract void writeNull();
 
+    public void writeObjectNull(Class<?> fieldClass) {
+        if ((this.context.features & (MASK_NULL_AS_DEFAULT_VALUE)) != 0) {
+            if (fieldClass == Character.class) {
+                writeString("\u0000");
+            } else {
+                writeRaw('{', '}');
+            }
+        } else {
+            writeNull();
+        }
+    }
+
     public void writeStringNull() {
         String raw;
         long features = this.context.features;
@@ -1176,6 +1188,16 @@ public abstract class JSONWriter
         }
     }
 
+    public final void writeDecimalNull() {
+        if ((this.context.features & MASK_NULL_AS_DEFAULT_VALUE) != 0) {
+            writeDouble(0.0);
+        } else if ((this.context.features & MASK_WRITE_NULL_NUMBER_AS_ZERO) != 0) {
+            writeInt32(0);
+        } else {
+            writeNull();
+        }
+    }
+
     public final void writeInt64Null() {
         if ((this.context.features & (MASK_NULL_AS_DEFAULT_VALUE | MASK_WRITE_NULL_NUMBER_AS_ZERO)) != 0) {
             writeInt64(0);
diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONWriterUTF16.java b/core/src/main/java/com/alibaba/fastjson2/JSONWriterUTF16.java
index 94ca4946c..a8b96ebaa 100644
--- a/core/src/main/java/com/alibaba/fastjson2/JSONWriterUTF16.java
+++ b/core/src/main/java/com/alibaba/fastjson2/JSONWriterUTF16.java
@@ -1045,7 +1045,7 @@ class JSONWriterUTF16
 
     public final void writeDecimal(BigDecimal value, long features, DecimalFormat format) {
         if (value == null) {
-            writeNumberNull();
+            writeDecimalNull();
             return;
         }
 
diff --git a/core/src/main/java/com/alibaba/fastjson2/JSONWriterUTF8.java b/core/src/main/java/com/alibaba/fastjson2/JSONWriterUTF8.java
index 0e91f1f52..0a2d70552 100644
--- a/core/src/main/java/com/alibaba/fastjson2/JSONWriterUTF8.java
+++ b/core/src/main/java/com/alibaba/fastjson2/JSONWriterUTF8.java
@@ -2371,7 +2371,7 @@ final class JSONWriterUTF8
     @Override
     public final void writeDecimal(BigDecimal value, long features, DecimalFormat format) {
         if (value == null) {
-            writeNumberNull();
+            writeDecimalNull();
             return;
         }
 
diff --git a/core/src/main/java/com/alibaba/fastjson2/internal/asm/MethodWriter.java b/core/src/main/java/com/alibaba/fastjson2/internal/asm/MethodWriter.java
index 372d1f733..4ac13b84d 100644
--- a/core/src/main/java/com/alibaba/fastjson2/internal/asm/MethodWriter.java
+++ b/core/src/main/java/com/alibaba/fastjson2/internal/asm/MethodWriter.java
@@ -301,6 +301,19 @@ public final class MethodWriter {
         visitInsn(Opcodes.I2D);
     }
 
+    public void cmpWithZero(Class<?> fieldClass) {
+        if (fieldClass == long.class) {
+            visitInsn(Opcodes.LCONST_0);
+            visitInsn(Opcodes.LCMP);
+        } else if (fieldClass == double.class) {
+            visitInsn(Opcodes.DCONST_0);
+            visitInsn(Opcodes.DCMPL);
+        } else if (fieldClass == float.class) {
+            visitInsn(Opcodes.FCONST_0);
+            visitInsn(Opcodes.FCMPL);
+        }
+    }
+
     public void lxor() {
         visitInsn(Opcodes.LXOR);
     }
@@ -416,6 +429,14 @@ public final class MethodWriter {
         visitInsn(Opcodes.DUP);
     }
 
+    public void dup(Class<?> fieldClass) {
+        if (fieldClass == long.class || fieldClass == double.class) {
+            visitInsn(Opcodes.DUP2);
+        } else {
+            visitInsn(Opcodes.DUP);
+        }
+    }
+
     public void dup2() {
         visitInsn(Opcodes.DUP2);
     }
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriter.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriter.java
index 9f56a1aa3..3c6df2c1b 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriter.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriter.java
@@ -340,7 +340,7 @@ public abstract class FieldWriter<T>
         }
 
         if (fieldClass == boolean.class) {
-            if (fieldValue == Boolean.FALSE) {
+            if (fieldValue.equals(Boolean.FALSE)) {
                 return;
             }
         } else if (fieldClass == byte.class
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalField.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalField.java
index 4534b5e51..a8679be8a 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalField.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalField.java
@@ -23,7 +23,7 @@ final class FieldWriterBigDecimalField<T>
         BigDecimal value = (BigDecimal) getFieldValue(object);
         if (value == null) {
             long features = this.features | jsonWriter.getFeatures();
-            if ((features & JSONWriter.Feature.WriteNulls.mask) == 0) {
+            if ((features & (JSONWriter.Feature.WriteNulls.mask | JSONWriter.Feature.NullAsDefaultValue.mask)) == 0) {
                 return false;
             }
         }
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalFunc.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalFunc.java
index 778c6923a..a3936a02f 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalFunc.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalFunc.java
@@ -50,7 +50,7 @@ final class FieldWriterBigDecimalFunc<T>
 
         if (value == null) {
             long features = this.features | jsonWriter.getFeatures();
-            if ((features & JSONWriter.Feature.WriteNulls.mask) == 0) {
+            if ((features & (JSONWriter.Feature.WriteNulls.mask | JSONWriter.Feature.NullAsDefaultValue.mask)) == 0) {
                 return false;
             }
         }
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalMethod.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalMethod.java
index eae70c1ae..5831d272d 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalMethod.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigDecimalMethod.java
@@ -51,7 +51,7 @@ final class FieldWriterBigDecimalMethod<T>
 
         if (value == null) {
             long features = this.features | jsonWriter.getFeatures();
-            if ((features & JSONWriter.Feature.WriteNulls.mask) == 0) {
+            if ((features & (JSONWriter.Feature.WriteNulls.mask | JSONWriter.Feature.NullAsDefaultValue.mask)) == 0) {
                 return false;
             }
         }
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigIntField.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigIntField.java
index 95d789bca..fb6e5247e 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigIntField.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigIntField.java
@@ -23,7 +23,7 @@ final class FieldWriterBigIntField<T>
         BigInteger value = (BigInteger) getFieldValue(object);
         if (value == null) {
             long features = this.features | jsonWriter.getFeatures();
-            if ((features & JSONWriter.Feature.WriteNulls.mask) == 0) {
+            if ((features & (JSONWriter.Feature.WriteNulls.mask | JSONWriter.Feature.NullAsDefaultValue.mask)) == 0) {
                 return false;
             }
         }
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigIntFunc.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigIntFunc.java
index 4fbe28cf8..50e5032f2 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigIntFunc.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterBigIntFunc.java
@@ -41,7 +41,7 @@ final class FieldWriterBigIntFunc<T>
         BigInteger value = function.apply(o);
         if (value == null) {
             long features = this.features | jsonWriter.getFeatures();
-            if ((features & JSONWriter.Feature.WriteNulls.mask) == 0) {
+            if ((features & (JSONWriter.Feature.WriteNulls.mask | JSONWriter.Feature.NullAsDefaultValue.mask)) == 0) {
                 return false;
             }
         }
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterDoubleFunc.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterDoubleFunc.java
index 2d8955573..1e1acaf3f 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterDoubleFunc.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterDoubleFunc.java
@@ -58,11 +58,12 @@ final class FieldWriterDoubleFunc<T>
 
         if (value == null) {
             long features = jsonWriter.getFeatures(this.features);
-            if ((features & JSONWriter.Feature.WriteNulls.mask) != 0
-                    && (features & JSONWriter.Feature.NotWriteDefaultValue.mask) == 0
-            ) {
+            if ((features & (JSONWriter.Feature.WriteNulls.mask | JSONWriter.Feature.NullAsDefaultValue.mask)) == 0) {
+                return false;
+            }
+            if ((features & JSONWriter.Feature.NotWriteDefaultValue.mask) == 0) {
                 writeFieldName(jsonWriter);
-                jsonWriter.writeNumberNull();
+                jsonWriter.writeDecimalNull();
                 return true;
             }
             return false;
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterFloatFunc.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterFloatFunc.java
index 5196f2267..2de63a517 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterFloatFunc.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterFloatFunc.java
@@ -58,11 +58,12 @@ final class FieldWriterFloatFunc<T>
 
         if (value == null) {
             long features = jsonWriter.getFeatures(this.features);
-            if ((features & JSONWriter.Feature.WriteNulls.mask) != 0
-                    && (features & JSONWriter.Feature.NotWriteDefaultValue.mask) == 0
-            ) {
+            if ((features & (JSONWriter.Feature.WriteNulls.mask | JSONWriter.Feature.NullAsDefaultValue.mask)) == 0) {
+                return false;
+            }
+            if ((features & JSONWriter.Feature.NotWriteDefaultValue.mask) == 0) {
                 writeFieldName(jsonWriter);
-                jsonWriter.writeNumberNull();
+                jsonWriter.writeDecimalNull();
                 return true;
             }
             return false;
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterInt16.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterInt16.java
index fbce556a3..d9ef572d0 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterInt16.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterInt16.java
@@ -46,7 +46,7 @@ abstract class FieldWriterInt16<T>
 
         if (value == null) {
             long features = this.features | jsonWriter.getFeatures();
-            if ((features & JSONWriter.Feature.WriteNulls.mask) == 0) {
+            if ((features & (JSONWriter.Feature.WriteNulls.mask | JSONWriter.Feature.NullAsDefaultValue.mask)) == 0) {
                 return false;
             }
             writeFieldName(jsonWriter);
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterInt8.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterInt8.java
index 7fe96c0c5..5ef1af2d6 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterInt8.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterInt8.java
@@ -45,7 +45,7 @@ abstract class FieldWriterInt8<T>
 
         if (value == null) {
             long features = this.features | jsonWriter.getFeatures();
-            if ((features & JSONWriter.Feature.WriteNulls.mask) == 0) {
+            if ((features & (JSONWriter.Feature.WriteNulls.mask | JSONWriter.Feature.NullAsDefaultValue.mask)) == 0) {
                 return false;
             }
             writeFieldName(jsonWriter);
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterObject.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterObject.java
index 3c181c02a..9817721d0 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterObject.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterObject.java
@@ -272,7 +272,10 @@ public class FieldWriterObject<T>
 
         // (features & JSONWriter.Feature.WriteNullNumberAsZero.mask) != 0
         if (value == null) {
-            if ((features & WriteNulls.mask) != 0 && (features & NotWriteDefaultValue.mask) == 0) {
+            if ((features & (JSONWriter.Feature.WriteNulls.mask | JSONWriter.Feature.NullAsDefaultValue.mask)) == 0) {
+                return false;
+            }
+            if ((features & NotWriteDefaultValue.mask) == 0) {
                 writeFieldName(jsonWriter);
                 if (array) {
                     jsonWriter.writeArrayNull();
@@ -283,7 +286,7 @@ public class FieldWriterObject<T>
                         || fieldClass == StringBuilder.class) {
                     jsonWriter.writeStringNull();
                 } else {
-                    jsonWriter.writeNull();
+                    jsonWriter.writeObjectNull(fieldClass);
                 }
                 return true;
             } else {
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterObjectFinal.java b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterObjectFinal.java
index 136965d4c..1ddaa3926 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterObjectFinal.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/FieldWriterObjectFinal.java
@@ -59,20 +59,18 @@ abstract class FieldWriterObjectFinal<T>
 
         if (value == null) {
             long features = this.features | jsonWriter.getFeatures();
-            if ((features & JSONWriter.Feature.WriteNulls.mask) != 0) {
-                writeFieldName(jsonWriter);
-
-                if (fieldClass.isArray()) {
-                    jsonWriter.writeArrayNull();
-                } else if (fieldClass == StringBuffer.class || fieldClass == StringBuilder.class) {
-                    jsonWriter.writeStringNull();
-                } else {
-                    jsonWriter.writeNull();
-                }
-                return true;
-            } else {
+            if ((features & (JSONWriter.Feature.WriteNulls.mask | JSONWriter.Feature.NullAsDefaultValue.mask)) == 0) {
                 return false;
             }
+            writeFieldName(jsonWriter);
+            if (fieldClass.isArray()) {
+                jsonWriter.writeArrayNull();
+            } else if (fieldClass == StringBuffer.class || fieldClass == StringBuilder.class) {
+                jsonWriter.writeStringNull();
+            } else {
+                jsonWriter.writeObjectNull(fieldClass);
+            }
+            return true;
         }
 
         ObjectWriter valueWriter = getObjectWriter(jsonWriter, fieldClass);
diff --git a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreatorASM.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreatorASM.java
index 4457c5ec7..79a625cbc 100644
--- a/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreatorASM.java
+++ b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreatorASM.java
@@ -1907,6 +1907,20 @@ public class ObjectWriterCreatorASM
 
         boolean writeAsString = (fieldWriter.features & WriteNonStringValueAsString.mask) != 0;
 
+        if (fieldClass == int.class && !writeAsString) {
+            String format = fieldWriter.format;
+            if ("string".equals(format)) {
+                mw.invokestatic("java/lang/Integer", "toString", "(I)Ljava/lang/String;");
+                mw.invokevirtual(TYPE_JSON_WRITER, "writeString", "(Ljava/lang/String;)V");
+            } else if (format != null) {
+                mw.visitLdcInsn(format);
+                mw.invokevirtual(TYPE_JSON_WRITER, "writeInt32", "(ILjava/lang/String;)V");
+            } else {
+                mw.invokevirtual(TYPE_JSON_WRITER, "writeInt32", "(I)V");
+            }
+            return;
+        }
+
         String methodName, methodDesc;
         if (fieldClass == boolean.class) {
             methodName = "writeBool";
@@ -2446,21 +2460,18 @@ public class ObjectWriterCreatorASM
                 || fieldClass == double[].class
         ) {
             gwFieldValueArray(mwc, fieldWriter, OBJECT, i);
-        } else if (fieldClass == int.class && !writeAsString) {
-            gwFieldValueInt32V(mwc, fieldWriter, OBJECT, i, false);
         } else if (fieldClass == char.class
                 || fieldClass == byte.class
                 || fieldClass == int.class
                 || fieldClass == short.class
                 || fieldClass == float.class
-                || fieldClass == double.class
         ) {
-            gwFieldName(mwc, fieldWriter, i);
-            gwValue(mwc, fieldWriter, OBJECT, i);
+            gwFieldValueInt32V(mwc, fieldWriter, OBJECT, i, false);
         } else if (fieldClass == int[].class) {
             gwFieldValueIntVA(mwc, fieldWriter, OBJECT, i, false);
-        } else if (fieldClass == long.class) {
-            gwFieldValueInt64V(mwc, fieldWriter, OBJECT, i, false);
+        } else if (fieldClass == long.class
+                || fieldClass == double.class) {
+            gwFieldValueInt64V(mwc, fieldWriter, OBJECT, i, true);
         } else if (fieldClass == long[].class
                 && mwc.provider.getObjectWriter(Long.class) == ObjectWriterImplInt64.INSTANCE
         ) {
@@ -2526,7 +2537,7 @@ public class ObjectWriterCreatorASM
         // writeFieldName(w);
         gwFieldName(mwc, fieldWriter, i);
 
-        // jw.writeNulll
+        // jw.writeNull
         mw.aload(JSON_WRITER);
         mw.invokevirtual(TYPE_JSON_WRITER, "writeNull", "()V");
 
@@ -2813,6 +2824,8 @@ public class ObjectWriterCreatorASM
             } else if (fieldClass == String.class) {
                 nullFeatures |= WriteNullStringAsEmpty.mask;
                 nullFeatures |= NullAsDefaultValue.mask;
+            } else {
+                nullFeatures |= NullAsDefaultValue.mask;
             }
             mwc.genIsEnabled(nullFeatures, notNull_);
 //            mw.iload(mwc.var(WRITE_NULLS));
@@ -2822,13 +2835,19 @@ public class ObjectWriterCreatorASM
         // writeFieldName(w);
         gwFieldName(mwc, fieldWriter, i);
 
-        // jw.writeNulll
+        // jw.writeNull
+        mw.aload(JSON_WRITER);
         String WRITE_NULL_METHOD;
+        String WRITE_NULL_DESC = "()V";
         if (fieldClass == AtomicLongArray.class
                 || fieldClass == AtomicIntegerArray.class
                 || Collection.class.isAssignableFrom(fieldClass)
                 || fieldClass.isArray()) {
             WRITE_NULL_METHOD = "writeArrayNull";
+        } else if (fieldClass == Float.class
+                || fieldClass == Double.class
+                || fieldClass == BigDecimal.class) {
+            WRITE_NULL_METHOD = "writeDecimalNull";
         } else if (Number.class.isAssignableFrom(fieldClass)) {
             WRITE_NULL_METHOD = "writeNumberNull";
         } else if (fieldClass == Boolean.class) {
@@ -2839,10 +2858,11 @@ public class ObjectWriterCreatorASM
                 || fieldClass == StringBuilder.class) {
             WRITE_NULL_METHOD = "writeStringNull";
         } else {
-            WRITE_NULL_METHOD = "writeNull";
+            WRITE_NULL_METHOD = "writeObjectNull";
+            WRITE_NULL_DESC = "(Ljava/lang/Class;)V";
+            mwc.loadFieldClass(i, fieldClass);
         }
-        mw.aload(JSON_WRITER);
-        mw.invokevirtual(TYPE_JSON_WRITER, WRITE_NULL_METHOD, "()V");
+        mw.invokevirtual(TYPE_JSON_WRITER, WRITE_NULL_METHOD, WRITE_NULL_DESC);
 
         mw.visitLabel(notNull_);
     }
@@ -3005,7 +3025,7 @@ public class ObjectWriterCreatorASM
         // writeFieldName(w);
         gwFieldName(mwc, fieldWriter, i);
 
-        // jw.writeNulll
+        // jw.writeNull
         mw.aload(JSON_WRITER);
         mw.invokevirtual(TYPE_JSON_WRITER, "writeArrayNull", "()V");
 
@@ -3032,20 +3052,17 @@ public class ObjectWriterCreatorASM
                 || fieldClass == double[].class
         ) {
             gwFieldValueArray(mwc, fieldWriter, OBJECT, i);
-        } else if (fieldClass == int.class && !writeAsString) {
-            gwFieldValueInt32V(mwc, fieldWriter, OBJECT, i, true);
         } else if (fieldClass == char.class
                 || fieldClass == byte.class
                 || fieldClass == short.class
                 || fieldClass == int.class
                 || fieldClass == float.class
-                || fieldClass == double.class
         ) {
-            gwFieldName(mwc, fieldWriter, i);
-            gwValue(mwc, fieldWriter, OBJECT, i);
+            gwFieldValueInt32V(mwc, fieldWriter, OBJECT, i, true);
         } else if (fieldClass == int[].class) {
             gwFieldValueIntVA(mwc, fieldWriter, OBJECT, i, true);
-        } else if (fieldClass == long.class) {
+        } else if (fieldClass == long.class
+                || fieldClass == double.class) {
             gwFieldValueInt64V(mwc, fieldWriter, OBJECT, i, true);
         } else if (fieldClass == long[].class
                 && mwc.provider.getObjectWriter(Long.class) == ObjectWriterImplInt64.INSTANCE
@@ -3239,7 +3256,7 @@ public class ObjectWriterCreatorASM
         gwFieldName(mwc, fieldWriter, i);
 
         mw.aload(JSON_WRITER);
-        mw.invokevirtual(TYPE_JSON_WRITER, "writeNumberNull", "()V");
+        mw.invokevirtual(TYPE_JSON_WRITER, "writeDecimalNull", "()V");
 
         mw.goto_(endIfNull_);
 
@@ -3300,7 +3317,7 @@ public class ObjectWriterCreatorASM
         gwFieldName(mwc, fieldWriter, i);
 
         mw.aload(JSON_WRITER);
-        mw.invokevirtual(TYPE_JSON_WRITER, "writeNumberNull", "()V");
+        mw.invokevirtual(TYPE_JSON_WRITER, "writeDecimalNull", "()V");
 
         mw.goto_(endIfNull_);
 
@@ -3484,7 +3501,7 @@ public class ObjectWriterCreatorASM
         mw.visitLabel(writeNull_);
         gwFieldName(mwc, fieldWriter, i);
 
-        // jw.writeNulll
+        // jw.writeNull
         mw.aload(JSON_WRITER);
         mw.invokevirtual(TYPE_JSON_WRITER, "writeNull", "()V");
 
@@ -3922,16 +3939,16 @@ public class ObjectWriterCreatorASM
         MethodWriter mw = mwc.mw;
         String format = fieldWriter.format;
         String classNameType = mwc.classNameType;
+        Class fieldClass = fieldWriter.fieldClass;
 
-        int FIELD_VALUE = mwc.var(long.class);
+        int FIELD_VALUE = mwc.var(fieldClass);
         int WRITE_DEFAULT_VALUE = mwc.var(NOT_WRITE_DEFAULT_VALUE);
         Label notDefaultValue_ = new Label(), endWriteValue_ = new Label();
 
         genGetObject(mwc, fieldWriter, i, OBJECT);
         mw.dup2();
-        mw.lstore(FIELD_VALUE);
-        mw.lconst_0();
-        mw.lcmp();
+        mw.storeLocal(fieldClass, FIELD_VALUE);
+        mw.cmpWithZero(fieldClass);
         mw.ifne(notDefaultValue_);
 
         if (fieldWriter.defaultValue == null) {
@@ -3941,21 +3958,28 @@ public class ObjectWriterCreatorASM
         }
         mw.visitLabel(notDefaultValue_);
 
-        boolean iso8601 = "iso8601".equals(format);
-        if (iso8601 || (fieldWriter.features & (WriteNonStringValueAsString.mask | WriteLongAsString.mask | BrowserCompatible.mask)) != 0) {
-            mw.aload(THIS);
-            mw.getfield(classNameType, fieldWriter(i), DESC_FIELD_WRITER);
+        if (fieldClass == long.class) {
+            boolean iso8601 = "iso8601".equals(format);
+            if (iso8601 || (fieldWriter.features & (WriteNonStringValueAsString.mask | WriteLongAsString.mask | BrowserCompatible.mask)) != 0) {
+                mw.aload(THIS);
+                mw.getfield(classNameType, fieldWriter(i), DESC_FIELD_WRITER);
 
-            mw.aload(JSON_WRITER);
-            mw.lload(FIELD_VALUE);
+                mw.aload(JSON_WRITER);
+                mw.lload(FIELD_VALUE);
 
-            mw.invokevirtual(TYPE_FIELD_WRITER, iso8601 ? "writeDate" : "writeInt64", METHOD_DESC_WRITE_J);
-        } else {
-            gwFieldName(mwc, fieldWriter, i);
+                mw.invokevirtual(TYPE_FIELD_WRITER, iso8601 ? "writeDate" : "writeInt64", METHOD_DESC_WRITE_J);
+            } else {
+                gwFieldName(mwc, fieldWriter, i);
 
-            mw.aload(JSON_WRITER);
-            mw.lload(FIELD_VALUE);
-            mw.invokevirtual(TYPE_JSON_WRITER, "writeInt64", "(J)V");
+                mw.aload(JSON_WRITER);
+                mw.lload(FIELD_VALUE);
+                mw.invokevirtual(TYPE_JSON_WRITER, "writeInt64", "(J)V");
+            }
+        } else if (fieldClass == double.class) {
+            gwFieldName(mwc, fieldWriter, i);
+            gwValue(mwc, fieldWriter, OBJECT, i);
+        } else {
+            throw new UnsupportedOperationException();
         }
 
         mw.visitLabel(endWriteValue_);
@@ -4019,14 +4043,16 @@ public class ObjectWriterCreatorASM
         MethodWriter mw = mwc.mw;
         String format = fieldWriter.format;
         String classNameType = mwc.classNameType;
+        Class<?> fieldClass = fieldWriter.fieldClass;
 
-        int FIELD_VALUE = mwc.var(int.class);
+        int FIELD_VALUE = mwc.var(fieldClass);
         int WRITE_DEFAULT_VALUE = mwc.var(NOT_WRITE_DEFAULT_VALUE);
         Label notDefaultValue_ = new Label(), endWriteValue_ = new Label();
 
         genGetObject(mwc, fieldWriter, i, OBJECT);
-        mw.dup();
-        mw.istore(FIELD_VALUE);
+        mw.dup(fieldClass);
+        mw.storeLocal(fieldClass, FIELD_VALUE);
+        mw.cmpWithZero(fieldClass);
         mw.ifne(notDefaultValue_);
 
         if (fieldWriter.defaultValue == null) {
@@ -4038,17 +4064,7 @@ public class ObjectWriterCreatorASM
 
         gwFieldName(mwc, fieldWriter, i);
 
-        mw.aload(JSON_WRITER);
-        mw.iload(FIELD_VALUE);
-        if ("string".equals(format)) {
-            mw.invokestatic("java/lang/Integer", "toString", "(I)Ljava/lang/String;");
-            mw.invokevirtual(TYPE_JSON_WRITER, "writeString", "(Ljava/lang/String;)V");
-        } else if (format != null) {
-            mw.visitLdcInsn(format);
-            mw.invokevirtual(TYPE_JSON_WRITER, "writeInt32", "(ILjava/lang/String;)V");
-        } else {
-            mw.invokevirtual(TYPE_JSON_WRITER, "writeInt32", "(I)V");
-        }
+        gwValue(mwc, fieldWriter, OBJECT, i);
 
         mw.visitLabel(endWriteValue_);
     }
@@ -4190,7 +4206,7 @@ public class ObjectWriterCreatorASM
         mw.invokevirtual(TYPE_JSON_WRITER, "writeString", "(Ljava/lang/String;)V");
         mw.goto_(endIfNull_);
 
-        // jw.writeNulll
+        // jw.writeNull
         mw.visitLabel(writeNullValue_);
         mw.aload(JSON_WRITER);
         mw.invokevirtual(TYPE_JSON_WRITER, "writeStringNull", "()V");


Test patch:
diff --git a/core/src/test/java/com/alibaba/fastjson2/issues/Issue364.java b/core/src/test/java/com/alibaba/fastjson2/issues/Issue364.java
index 9582d2885..6cda849b4 100644
--- a/core/src/test/java/com/alibaba/fastjson2/issues/Issue364.java
+++ b/core/src/test/java/com/alibaba/fastjson2/issues/Issue364.java
@@ -11,7 +11,7 @@ public class Issue364 {
     @Test
     public void test() {
         TestBean bean = new TestBean();
-        assertEquals("{\"msg\":\"\"}", JSON.toJSONString(bean, JSONWriter.Feature.NullAsDefaultValue));
+        assertEquals("{\"bean\":{},\"msg\":\"\"}", JSON.toJSONString(bean, JSONWriter.Feature.NullAsDefaultValue));
     }
 
     @Data
diff --git a/core/src/test/java/com/alibaba/fastjson2/issues_3100/Issue3186.java b/core/src/test/java/com/alibaba/fastjson2/issues_3100/Issue3186.java
new file mode 100644
index 000000000..c15eadbb0
--- /dev/null
+++ b/core/src/test/java/com/alibaba/fastjson2/issues_3100/Issue3186.java
@@ -0,0 +1,30 @@
+package com.alibaba.fastjson2.issues_3100;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONWriter;
+import lombok.Getter;
+import lombok.Setter;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class Issue3186 {
+    @Test
+    public void test() {
+        assertEquals("{}", JSON.toJSONString(new Bean(), JSONWriter.Feature.NotWriteDefaultValue));
+        assertEquals("{}", new String(JSON.toJSONBytes(new Bean(), JSONWriter.Feature.NotWriteDefaultValue)));
+    }
+
+    @Getter
+    @Setter
+    public static class Bean {
+        private boolean booleanV;
+        private char charV;
+        private byte byteV;
+        private int intV;
+        private short shortV;
+        private float floatV;
+        private double doubleV;
+        private long longV;
+    }
+}
diff --git a/core/src/test/java/com/alibaba/fastjson2/issues_3500/Issue3515.java b/core/src/test/java/com/alibaba/fastjson2/issues_3500/Issue3515.java
new file mode 100644
index 000000000..9d440e73e
--- /dev/null
+++ b/core/src/test/java/com/alibaba/fastjson2/issues_3500/Issue3515.java
@@ -0,0 +1,56 @@
+package com.alibaba.fastjson2.issues_3500;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.JSONWriter;
+import lombok.Getter;
+import lombok.Setter;
+import org.junit.jupiter.api.Test;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.List;
+import java.util.Map;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+public class Issue3515 {
+    @Test
+    public void test() throws Exception {
+        String jsonString = JSON.toJSONString(new Bean(), JSONWriter.Feature.NullAsDefaultValue);
+        Bean bean = JSON.parseObject(jsonString, Bean.class);
+        assertFalse(bean.getBoolVal());
+        assertEquals((byte) 0, bean.getByteVal());
+        assertEquals('\u0000', bean.getCharVal());
+        assertEquals((short) 0, bean.getShortVal());
+        assertEquals(0, bean.getIntVal());
+        assertEquals(0L, bean.getLongVal());
+        assertEquals(0.0F, bean.getFloatVal());
+        assertEquals(0.0D, bean.getDoubleVal());
+        assertEquals("", bean.getStringVal());
+        assertEquals("{}", bean.getMapVal().toString());
+        assertEquals("[]", bean.getListVal().toString());
+        assertEquals(BigInteger.ZERO, bean.getIntegerVal());
+        assertEquals(new BigDecimal("0.0"), bean.getDecimalVal());
+        assertEquals("{}", bean.getObjectVal().toString());
+    }
+
+    @Getter
+    @Setter
+    static class Bean {
+        private Boolean boolVal;
+        private Byte byteVal;
+        private Character charVal;
+        private Short shortVal;
+        private Integer intVal;
+        private Long longVal;
+        private Float floatVal;
+        private Double doubleVal;
+        private String stringVal;
+        private Map<?, ?> mapVal;
+        private List<?> listVal;
+        private BigDecimal decimalVal;
+        private BigInteger integerVal;
+        private Object objectVal;
+    }
+}
diff --git a/core/src/test/java/com/alibaba/fastjson2/v1issues/issue_3400/Issue_20201016_01.java b/core/src/test/java/com/alibaba/fastjson2/v1issues/issue_3400/Issue_20201016_01.java
index e8c500390..92111e7df 100644
--- a/core/src/test/java/com/alibaba/fastjson2/v1issues/issue_3400/Issue_20201016_01.java
+++ b/core/src/test/java/com/alibaba/fastjson2/v1issues/issue_3400/Issue_20201016_01.java
@@ -19,7 +19,7 @@ public class Issue_20201016_01 {
 
         String s = JSON.toJSONString(config, JSONWriter.Feature.WriteNulls, JSONWriter.Feature.NullAsDefaultValue);
 
-        assertEquals("{\"agent\":null,\"creator\":{\"account\":\"account\",\"name\":\"name\",\"workid\":\"\"},\"owner\":{\"account\":\"account\",\"name\":\"name\",\"workid\":\"\"}}", s);
+        assertEquals("{\"agent\":{},\"creator\":{\"account\":\"account\",\"name\":\"name\",\"workid\":\"\"},\"owner\":{\"account\":\"account\",\"name\":\"name\",\"workid\":\"\"}}", s);
     }
 
     @Test