该把代码抽成方法的情况是:同一逻辑在三处以上出现,或业务规则与细节操作混杂;应封装有明确输入输出的逻辑,避免只有副作用的代码。

什么时候该把代码抽成方法
不是所有重复都值得封装。真正该动刀的情况是:同一段逻辑在三个以上地方出现,或者某段代码里混着业务规则和细节操作(比如既拼接字符串又校验空值)。这时候硬写三遍,改一处漏两处,比抽方法还费时间。
常见错误现象:NullPointerException 在不同方法里反复出现,只因为每处都手写 if (obj == null);或者数据库字段映射逻辑散落在五个 service 方法里,字段名改了得逐个搜。
- 优先封装「有明确输入输出」的逻辑,比如
formatOrderNo()、parseJsonString() - 避免封装「只有副作用」的代码,比如直接调
System.out.println()或修改全局变量——这种抽出来反而难测试、难复用 - 如果方法内部要频繁访问
this的多个字段,说明它本就该属于当前类;但如果只用到 1–2 个参数,大概率可以改成静态方法
参数怎么设计才不容易返工
参数太多(超过 4 个)、类型太泛(全用 Object 或 Map)、或者顺序容易记混,都是重构后第二周就被打回原形的高发原因。
使用场景:比如处理用户注册,原始代码里到处是 createUser(String name, String email, int age, boolean isVip),但很快发现地区、来源渠道也要加进来——参数列表就失控了。
- 参数超过 3 个时,优先建一个
UserInput类封装,而不是堆参数 - 布尔参数慎用,
sendEmail(true)比sendEmail(true, false, true)还难懂;改用枚举或带名方法,比如sendWelcomeEmail()和sendReminderEmail() - 避免
null作为合法参数值,除非业务真需要区分“未传”和“传了 null”。更稳妥的是用Optional或直接抛IllegalArgumentException
private 还是 public?static 还是非 static?
这不是访问权限问题,而是语义问题。错用修饰符会导致后续想复用时卡住,或者单元测试写不下去。
常见错误现象:把 calculateTax() 写成 private,结果另一个 service 也要算税,只能复制粘贴;或者写成 public static,但里面偷偷调用了 this.getConfig(),一调就 NullPointerException。
- 只被当前类调用 →
private;可能被子类覆盖 →protected;明确要被其他模块调用 →public - 不依赖实例状态(没读
this.xxx)→ 用static;否则必须是非 static。别为了“看起来工具化”硬加static - 如果方法里用了 Spring 注入的
@Autowired成员,它就不可能是static,强行加只会让 IDE 报红、运行时报错
重构后跑不通?先盯这三个地方
不是语法错了,而是调用上下文变了。Java 编译器不报错,但行为已偏移。
性能影响:原来内联的简单计算,抽成方法后多了栈帧开销——但现代 JVM 基本会内联优化,除非方法体过大或含分支预测失败;真正拖慢的往往是日志、远程调用、锁这些被无意带进来的操作。
- 检查异常处理是否迁移完整:原代码里
try-catch了IOException,抽方法后忘了声明throws IOException,编译直接过不去 - 留意线程安全性:原逻辑在单线程里没问题,抽成公共方法后被多线程并发调用,而方法里用了共享的
SimpleDateFormat或ArrayList,就会出数据错乱 - 确认返回值是否被隐式修改:比如原代码返回
new ArrayList(list),抽方法后不小心返回了list本身,调用方一改就污染源头
最容易被忽略的是方法命名里的动词精度。process()、handle() 这类词等于没说;normalizePhoneNumber() 才让人一眼看懂边界——毕竟重构不是为了少写几行,而是让下一个人敢改、能猜对。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











