Repository: alibaba/fastjson2
Pull request #3534 (2025-05-01 20:53:21)

fix skip value setting when field is final and not empty collection i…
…nitialized, for issue #2944

### What this PR does / why we need it?

fix skip value setting when field is final and not empty collection initialized

### 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/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<T>
                     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<T>
                     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;


Test patch:
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<Employee> 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<Employee> employees;
+
+        public Department(String name, List<Employee> 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 + '\'' +
+                    '}';
+        }
+    }
+}