Why FastJSON Calls isChinaName() During Serialization and How to Fix It
An unexpected NullPointerException occurs when adding a simple log line to a Java DTO, revealing that FastJSON’s serialization process invokes methods like isChinaName(), getXxx(), and isXxx() via ASM-generated serializers, and the article explains the underlying mechanism, common pitfalls, and best‑practice annotations to avoid such bugs.
Recently a very simple feature was added: a log line was inserted before the nightly release. After deployment a flood of alerts appeared, the code was rolled back, and the added log line was removed. The root cause was a NullPointerException triggered during serialization.
Reproducing the Issue
A CountryDTO class was defined:
public class CountryDTO {
private String country;
public void setCountry(String country) { this.country = country; }
public String getCountry() { return this.country; }
public Boolean isChinaName() { return this.country.equals("中国"); }
}A test class FastJonTest serializes an instance of CountryDTO using FastJSON:
public class FastJonTest {
@Test
public void testSerialize() {
CountryDTO countryDTO = new CountryDTO();
String str = JSON.toJSONString(countryDTO);
System.out.println(str);
}
}The runtime error shows a NullPointerException at isChinaName(). The problem is that during serialization FastJSON calls isChinaName() while this.country is still null.
Why Does Serialization Invoke isChinaName()?
FastJSON uses ASM to generate a serializer class (e.g., ASMSerializer_1_CountryDTO) at runtime. The generated write method delegates to JavaBeanSerializer, which obtains an ObjectWriter via getObjectWriter(). Inside getObjectWriter(), FastJSON calls SerializeConfig#createJavaBeanSerializer and ultimately TypeUtils#computeGetters to collect getter methods.
The computeGetters logic scans all public methods of the class and includes:
Methods annotated with @JSONField(serialize = false, name = "xxx") (excluded from serialization).
Methods starting with get (standard getters).
Methods starting with is (boolean getters).
Therefore isChinaName() is treated as a getter and is invoked during serialization, causing the NullPointerException when the underlying field is null.
Serialization Flowchart
Example Code Demonstrating Common Cases
/**
* case1: @JSONField(serialize = false)
* case2: getXxx() returns void
* case3: isXxx() returns non‑boolean
* case4: @JSONType(ignores = "xxx")
*/
@JSONType(ignores = "otherName")
public class CountryDTO {
private String country;
public void setCountry(String country) { this.country = country; }
public String getCountry() { return this.country; }
public Boolean isChinaName() { System.out.println("isChinaName() executed!!"); return true; }
public String getEnglishName() { System.out.println("getEnglishName() executed!!"); return "lucy"; }
@JSONField(serialize = false)
public static void queryCountryList() { System.out.println("queryCountryList() executed!!"); }
@JSONField(serialize = false)
public String getOtherName() { System.out.println("getOtherName() executed!!"); return "lucy"; }
@JSONField(serialize = false)
public String getEnglishName2() { System.out.println("getEnglishName2() executed!!"); return "lucy"; }
@JSONField(serialize = false)
public void getEnglishName3() { System.out.println("getEnglishName3() executed!!"); }
@JSONField(serialize = false)
public String isChinaName2() { System.out.println("isChinaName2() executed!!"); return "isChinaName2"; }
}Running the test produces:
isChinaName() executed!!
getEnglishName() executed!!
{"chinaName":true,"englishName":"lucy"}Best Practice for Controlling Serialization
To avoid accidental method invocation during serialization, explicitly exclude methods with @JSONField(serialize = false). This makes the serialization intent clear and prevents NullPointerExceptions caused by uninitialized fields.
By following this convention, developers can quickly identify which methods participate in serialization and maintain consistent code quality across the project.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Code Ape Tech Column
Former Ant Group P8 engineer, pure technologist, sharing full‑stack Java, job interview and career advice through a column. Site: java-family.cn
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
