Java开发复盘:继承字段隐藏引发的隐形数据赋值异常
做业务迭代开发很多人都会用继承复用实体类、DTO、参数模型。父类定义公共字段子类扩展业务字段日常写起来很省事也能统一项目字段结构。但长期迭代下来团队多人维护的情况下很容易出现一种非常隐蔽的编码问题子类重复定义父类已存在的字段。新手基本不知道 Java 字段隐藏的特性只觉得名字一样无所谓编译不报错、启动不报错测试简单场景也没问题。直到上线后偶尔出现字段赋值为空、数据覆盖不掉、更新无效的问题排查起来完全摸不着头脑。我之前在老项目迭代就碰到过这个问题同样的字段set赋值成功get拿出来永远是null代码逻辑没有任何报错断点调试看着赋值正常出方法就失效。最后一层层排查才发现是子类和父类存在同名成员变量出现了字段隐藏。Java 的方法重写是覆盖但字段不存在重写只会隐藏。父类、子类拥有两个完全独立的同名字段内存中是两份数据互不干扰。这就造成了非常诡异的现象代码里看似在操作同一个字段实际根据引用类型不同操作的是完全不同的内存变量。最常见的场景就是入参接收、对象拷贝、框架赋值。比如前端传参过来用子类接收参数框架反射赋值给子类的同名字段。业务代码里用父类引用接收对象读取字段时读的是父类的空字段永远拿不到子类已经赋值的数据。全程无异常、无日志提示就是数据对不上。还有对象拷贝、工具类赋值的场景问题会更隐蔽。很多人用工具类做对象属性拷贝依赖反射遍历字段赋值。遇到父子类同名字段不同工具的遍历顺序、赋值规则不一样有的拷贝成功、有的直接跳过。导致本地测试环境正常线上偶尔拷贝失效字段数据丢失完全没有规律。团队迭代代码越多继承层级越深这种问题出现的概率越高。更坑的是日志打印误导判断。很多实体重写了 toString 方法只打印当前类字段或者只打印父类字段。调试时打印对象看到字段有值实际运行逻辑读取的是另一个隐藏字段数值为空。肉眼看着数据正常代码执行结果异常极大拉长排查时间。这类问题基本都是团队协作不规范导致的。多人迭代项目没人梳理继承关系新人改代码不知道父类已有字段随手在子类重新定义一遍。注解、默认值、字段类型还可能和父类不一样进一步加剧数据错乱。有的子类字段加了注解父类同名字段没有注解或者反之。序列化、数据库映射、参数校验只生效其中一个导致对接、入库、解析各种隐性bug。长期维护老项目的人应该都有体会继承滥用真的很容易堆积隐患。字段隐藏这种问题不属于代码错误属于语法特性带来的逻辑歧义。编译器不会提醒IDE 大部分时候也不会强警告全靠开发自己规避。现在我写代码除非是非常稳定的公共基础字段否则尽量少用实体继承。就算用继承也会严格核对父子类字段杜绝同名重复定义。很多看似无伤大雅的代码习惯日积月累就是线上最难排查的偶发故障。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →