Java中为何要将实例变量赋值给局部变量后操作?
该局部变量写法的核心作用
这个是Java并发场景下处理实例字段访问的经典稳妥写法,不是Spring特有的编码风格,不直接写this.webServer.stop()主要是为了规避两类问题:
规避并发场景下的空指针竞态风险
如果直接按字段访问的方式写判空+调用逻辑:if (this.webServer != null) { // 这行执行前,webServer实例字段可能被其他线程修改为null this.webServer.stop(); }上述代码里对
this.webServer的判空读、调用方法前的读是两次独立的内存访问,在多线程环境下两次访问之间,字段值完全可能被其他线程改写为null,直接导致stop()调用抛空指针,反而把catch块本来要抛出的原始业务异常覆盖掉,干扰问题排查。
把字段值先赋值给局部变量,相当于把当前时刻读到的引用快照存到线程私有的栈内存里,局部变量不会被其他线程修改,后续判空、方法调用都操作这个固定的快照值,从根源上避免了这个竞态窗口。哪怕赋值时读到的是null,后续判空跳过stop逻辑即可,和原本的业务语义完全一致。低代价的性能优化
Spring中webServer这类生命周期字段通常会用volatile修饰保证多线程可见性,每次读取volatile字段都需要遵循JMM的主内存访问语义,开销比读取栈上局部变量高。将字段值缓存到局部变量后,后续两次使用(判空、调用方法)都不需要重复访问主存,几乎没有额外编码成本。
补充:如果连判空都不写直接调用
this.webServer.stop(),只要异常发生在webServer初始化完成之前,就会直接抛空指针,连最基本的异常场景兼容都做不到。
内容的提问来源于stack exchange,提问作者AntonBoarf
相关产品推荐
相关产品推荐

