Repository: alibaba/fastjson2
Pull request #3541 (2025-05-08 15:59:37)

fix only return null when fist char is n, for issue #3537
### What this PR does / why we need it?

fix only return null when fist char is n

### 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/FieldReaderObject.java b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderObject.java
index ed962ac60..b857996ef 100644
--- a/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderObject.java
+++ b/core/src/main/java/com/alibaba/fastjson2/reader/FieldReaderObject.java
@@ -123,6 +123,7 @@ public class FieldReaderObject<T>
 
         Object value;
         try {
+            char first = jsonReader.current();
             if (jsonReader.nextIfNullOrEmptyString()) {
                 if (defaultValue != null) {
                     value = defaultValue;
@@ -135,7 +136,7 @@ public class FieldReaderObject<T>
                 } else if (fieldClass == Optional.class) {
                     value = Optional.empty();
                 } else {
-                    value = null;
+                    value = first == 'n' ? null : "";
                 }
             } else if (jsonReader.jsonb) {
                 if (fieldClass == Object.class) {
diff --git a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderSeeAlso.java b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderSeeAlso.java
index 191f481bd..90e4421c4 100644
--- a/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderSeeAlso.java
+++ b/core/src/main/java/com/alibaba/fastjson2/reader/ObjectReaderSeeAlso.java
@@ -243,7 +243,7 @@ final class ObjectReaderSeeAlso<T>
             JSONReader.Context context = jsonReader.getContext();
             long features3, hash = jsonReader.readFieldNameHashCode();
             JSONReader.AutoTypeBeforeHandler autoTypeFilter = context.getContextAutoTypeBeforeHandler();
-            if (hash == getTypeKeyHash()
+            if ((hash == getTypeKeyHash() || (seeAlsoDefault != null && seeAlsoDefault != Void.class))
                     && ((((features3 = (features | getFeatures() | context.getFeatures())) & JSONReader.Feature.SupportAutoType.mask) != 0) || autoTypeFilter != null)
             ) {
                 ObjectReader reader = null;


Test patch:
diff --git a/core/src/test/java/com/alibaba/fastjson2/issues_3500/Issue3537.java b/core/src/test/java/com/alibaba/fastjson2/issues_3500/Issue3537.java
new file mode 100644
index 000000000..3eead13cb
--- /dev/null
+++ b/core/src/test/java/com/alibaba/fastjson2/issues_3500/Issue3537.java
@@ -0,0 +1,39 @@
+package com.alibaba.fastjson2.issues_3500;
+
+import com.alibaba.fastjson2.JSON;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+public class Issue3537 {
+    @Test
+    public void test() {
+        String json = "{\"value\":\"\"}";
+        SimpleTestValue s = JSON.parseObject(json, SimpleTestValue.class);
+        assertEquals("", s.getValue());
+        json = "{\"value\":null}";
+        s = JSON.parseObject(json, SimpleTestValue.class);
+        assertNull(s.getValue());
+    }
+
+    public static class SimpleTestValue {
+        private Object value;
+
+        // 标准 getter/setter
+        public Object getValue() {
+            return value;
+        }
+        public void setValue(Object value) {
+            this.value = value;
+        }
+
+        // 自定义 getter 会导致问题
+        public List<String> getRelates() {
+            return Collections.emptyList();
+        }
+    }
+}
diff --git a/core/src/test/java/com/alibaba/fastjson2/issues_3500/Issue3540.java b/core/src/test/java/com/alibaba/fastjson2/issues_3500/Issue3540.java
new file mode 100644
index 000000000..916153644
--- /dev/null
+++ b/core/src/test/java/com/alibaba/fastjson2/issues_3500/Issue3540.java
@@ -0,0 +1,73 @@
+package com.alibaba.fastjson2.issues_3500;
+
+import com.alibaba.fastjson2.JSON;
+import com.alibaba.fastjson2.annotation.JSONType;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+public class Issue3540 {
+    @Test
+    public void exceptUseSeeAlsoDefault() {
+        final String json = "                {\n" +
+                "                    \"name\": \"tom\",\n" +
+                "                    \"age\": 18\n" +
+                "                }";
+        IAnimal animal = JSON.parseObject(json, IAnimal.class);
+        assertEquals(Dog.class, animal.getClass());
+    }
+
+    @Test
+    public void exceptUseSeeAlsoDefault2() {
+        final String json = "                {\n" +
+                "                    \"@type\": \"\",\n" +
+                "                    \"name\": \"tom\",\n" +
+                "                    \"age\": 18\n" +
+                "                }";
+        IAnimal animal = JSON.parseObject(json, IAnimal.class);
+        assertEquals(Dog.class, animal.getClass());
+    }
+
+    @Test
+    public void useTypeForSeeAlso() {
+        final String json = "                {\n" +
+                "                    \"@type\": \"Dog\",\n" +
+                "                    \"name\": \"tom\",\n" +
+                "                    \"age\": 18\n" +
+                "                }";
+        IAnimal animal = JSON.parseObject(json, IAnimal.class);
+        assertEquals(Dog.class, animal.getClass());
+    }
+
+    @JSONType(seeAlso = Dog.class, seeAlsoDefault = Dog.class)
+    public interface IAnimal {
+        String getName();
+
+        int getAge();
+    }
+
+    @JSONType(typeName = "Dog")
+    public static class Dog
+            implements IAnimal {
+        private String name;
+        private int age;
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public void setAge(int age) {
+            this.age = age;
+        }
+
+        @Override
+        public String getName() {
+            return null;
+        }
+
+        @Override
+        public int getAge() {
+            return 0;
+        }
+    }
+}