fix not write default value for primitive types, for issue #3186

This commit is contained in:
yanxutao89 2025-04-22 22:28:38 +08:00
parent 2f1f77bd6d
commit 5d2a56d38b
4 changed files with 102 additions and 44 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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,6 +3949,7 @@ public class ObjectWriterCreatorASM
}
mw.visitLabel(notDefaultValue_);
if (fieldClass == long.class) {
boolean iso8601 = "iso8601".equals(format);
if (iso8601 || (fieldWriter.features & (WriteNonStringValueAsString.mask | WriteLongAsString.mask | BrowserCompatible.mask)) != 0) {
mw.aload(THIS);
@ -3957,6 +3966,12 @@ public class ObjectWriterCreatorASM
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 +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_);
}

View File

@ -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;
}
}