Java调用RequestBuilder设置属性后值仍为null的原因排查
Java建造者模式赋值后属性全为null问题排查
问题复现
相关代码
Request类定义:
public class Request { String attribute1; String attribute2; String attribute3; String s1 = "attr1 is:"+ attribute1+", attr2 is: "+attribute2+", "+"attr3 is: "+attribute3; @Override public String toString() { return "[" + s1 + "]"; } }
RequestBuilder建造者类定义:
package com.test; public class RequestBuilder { private final Request request; public RequestBuilder() { request = new Request(); } public static void main(String[] args) { System.out.println(new RequestBuilder().setAttr1("one").setAttr3("three").buildrequest()); } public Request buildrequest() { return request; } public RequestBuilder setAttr1(String attr1) { request.attribute1 = attr1; return this; } public RequestBuilder setAttr2(String attr2) { request.attribute2 = attr2; return this; } public RequestBuilder setAttr3(String attr3) { request.attribute3 = attr3; return this; } }
实际运行输出:
[attr1 is:null, attr2 is: null, attr3 is: null]
预期目标:不定义Request类的带参构造函数,仅通过setter方法配合RequestBuilder实现动态属性赋值,上述代码执行后attr1、attr3应为非null值。
错误原因
- 核心问题是成员变量
s1的赋值时机错误:Java类的成员变量初始化逻辑会在对象实例化时立刻执行,也就是new Request()执行的瞬间,就会完成s1的字符串拼接。此时attribute1/attribute2/attribute3还未被Builder的setter方法赋值,均为引用类型默认值null,因此s1从Request实例创建完成开始,就固定为全null拼接后的字符串。 - 后续调用setAttr1、setAttr3方法仅修改了
attribute1、attribute3本身的取值,提前计算完成存储在s1中的字符串不会自动同步更新,因此调用toString()时永远返回实例化阶段生成的全null内容。
修复方案
将s1的拼接逻辑移到toString()方法内部,不要提前作为成员变量初始化,这样每次调用toString()时,都会读取当前最新的属性值完成拼接,无需新增带参构造函数,也不需要修改现有Builder的逻辑:
public class Request { String attribute1; String attribute2; String attribute3; @Override public String toString() { String s1 = "attr1 is:"+ attribute1+", attr2 is: "+attribute2+", "+"attr3 is: "+attribute3; return "[" + s1 + "]"; } }
修复后运行main方法,输出结果为:[attr1 is:one, attr2 is: null, attr3 is: three],符合预期。
内容的提问来源于stack exchange,提问作者anon
相关产品推荐
相关产品推荐

