From 61dc7e16e188c3fba3a99b93fa88f05691427150 Mon Sep 17 00:00:00 2001 From: yanxutao89 <910135896@qq.com> Date: Fri, 2 May 2025 04:50:04 +0800 Subject: [PATCH] fix skip value setting when field is final and not empty collection initialized, for issue #2944 --- .../fastjson2/reader/ObjectReaderAdapter.java | 12 ++++ .../ObjectReaderNoneDefaultConstructor.java | 12 ++++ .../fastjson2/issues_2900/Issue2944.java | 65 +++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 core/src/test/java/com/alibaba/fastjson2/issues_2900/Issue2944.java diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderAdapter.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderAdapter.java index 046b59ca9..0caa3b5c0 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderAdapter.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderAdapter.java @@ -7,6 +7,7 @@ import com.alibaba.fastjson2.util.Fnv; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.*; import java.util.function.Consumer; @@ -697,6 +698,17 @@ public class ObjectReaderAdapter continue; } + if (fieldReader.field != null && Modifier.isFinal(fieldReader.field.getModifiers())) { + try { + Object value = fieldReader.method.invoke(object); + if (value instanceof Collection && !((Collection) value).isEmpty()) { + continue; + } + } catch (Exception e) { + // just ignore + } + } + try { if (fieldValue.getClass() == fieldReader.fieldType) { fieldReader.accept(object, fieldValue); diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderNoneDefaultConstructor.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderNoneDefaultConstructor.java index 19ff68369..eecdb649f 100644 --- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderNoneDefaultConstructor.java +++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderNoneDefaultConstructor.java @@ -6,6 +6,7 @@ import com.alibaba.fastjson2.util.TypeUtils; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.*; import java.util.function.BiFunction; @@ -563,6 +564,17 @@ public class ObjectReaderNoneDefaultConstructor continue; } + if (fieldReader.field != null && Modifier.isFinal(fieldReader.field.getModifiers())) { + try { + Object value = fieldReader.method.invoke(object); + if (value instanceof Collection && !((Collection) value).isEmpty()) { + continue; + } + } catch (Exception e) { + // just ignore + } + } + Class valueClass = fieldValue.getClass(); Class fieldClass = fieldReader.fieldClass; Type fieldType = fieldReader.fieldType; diff --git a/core/src/test/java/com/alibaba/fastjson2/issues_2900/Issue2944.java b/core/src/test/java/com/alibaba/fastjson2/issues_2900/Issue2944.java new file mode 100644 index 000000000..6735e7bfc --- /dev/null +++ b/core/src/test/java/com/alibaba/fastjson2/issues_2900/Issue2944.java @@ -0,0 +1,65 @@ +package com.alibaba.fastjson2.issues_2900; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; +import lombok.Getter; +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +public class Issue2944 { + @Test + public void test() { + List employees = new ArrayList<>(); + employees.add(new Employee(0, "John")); + employees.add(new Employee(1, "Jane")); + employees.add(new Employee(2, "Bob")); + Department department = new Department("dev", employees); + + String payload = JSON.toJSONString(department); + JSONObject jsonObject = JSON.parseObject(payload); + Department parsed = jsonObject.toJavaObject(Department.class); + assertEquals(payload, JSON.toJSONString(parsed)); + } + + @Getter + static class Department { + private final String name; + private final List employees; + + public Department(String name, List employees) { + this.name = name; + this.employees = employees; + } + + @Override + public String toString() { + return "Department{" + + "name='" + name + '\'' + + ", employees=" + employees + + '}'; + } + } + + @Getter + static class Employee { + private final Integer id; + private final String name; + + public Employee(int id, String name) { + this.id = id; + this.name = name; + } + + @Override + public String toString() { + return "Employee{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } + } +}