必须使用 this.name = name; 否则同名形参会遮蔽成员变量,导致赋值失效、字段保持默认值,引发静默逻辑错误。

因为构造器里参数名和成员变量名一样时,不加 this 就会把值赋给参数自己,而不是类的字段。
形参自动遮蔽同名成员变量
Java 规定:当局部变量(包括形参)与成员变量同名时,局部变量优先可见。编译器默认把赋值语句中的变量名当作局部变量处理,导致成员变量根本没被触碰。
- 写
name = name;→ 实际是“把参数 name 的值赋给参数 name”,毫无意义 - 写
this.name = name;→ 明确告诉编译器:“左边是当前对象的 name 字段,右边是传进来的参数” - 成员变量保持默认值:引用类型为
null,数值类型为0或false
IDE 不报错,但逻辑已失效
这种错误不会导致编译失败,运行时也不会立即崩溃,而是静默地让对象处于“半初始化”状态。
- IntelliJ 等工具虽能高亮提示,但若关闭 inspection 或忽略警告,问题就埋下了
- 单元测试可能“侥幸通过”:比如
int age默认为 0,某些断言恰好成立,掩盖了未赋值事实 - 后续调用 getter 返回
null或0,排查时容易误判为业务逻辑或数据源问题
局部变量声明进一步加剧混淆
有些初学者会在构造器里重复声明同名变量,比如:String name = name;,这不仅没赋值给成员变量,还额外创建了一个局部变量。
- 该局部变量只在构造器内有效,方法结束即销毁
- 成员变量仍为
null,且 IDE 可能不报错(语法合法) - 典型表现:new 出的对象,调用
getName()返回null,但代码看起来“写了赋值”
缺少封装意识,绕过 setter 直接操作字段
初学者常直接在构造器中写 name = ...,却没意识到:如果字段是 private,外部根本无法访问;而正确做法应统一通过 this.name = ... 赋值,或调用 setName(...)。
- 用
private字段 + 公开 setter 是标准实践,但构造器中仍需用this区分 - 若误写成
setName(name)却没在 setter 里加this.name = name,同样失败 - 本质问题不是“能不能写”,而是“写给谁”——必须明确目标是当前实例的字段











