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..24559ade2 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 o2i(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 } 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/ObjectWriterCreatorASM.java b/core/src/main/java/com/alibaba/fastjson2/writer/ObjectWriterCreatorASM.java index 4457c5ec7..98f1a31bd 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 ) { @@ -3032,20 +3043,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 @@ -3922,16 +3930,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.o2i(fieldClass); mw.ifne(notDefaultValue_); if (fieldWriter.defaultValue == null) { @@ -3941,21 +3949,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 { + 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"); + } + } else if (fieldClass == double.class) { gwFieldName(mwc, fieldWriter, i); - - mw.aload(JSON_WRITER); - mw.lload(FIELD_VALUE); - mw.invokevirtual(TYPE_JSON_WRITER, "writeInt64", "(J)V"); + gwValue(mwc, fieldWriter, OBJECT, i); + } else { + throw new UnsupportedOperationException(); } mw.visitLabel(endWriteValue_); @@ -4019,14 +4034,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.o2i(fieldClass); mw.ifne(notDefaultValue_); if (fieldWriter.defaultValue == null) { @@ -4038,17 +4055,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_); } 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; + } +}