短路与(&&)可防止空指针异常,核心是将判空与取值写在同一表达式中,利用左侧为false时跳过右侧执行的特性;必须逐层判空,如user != null && user.getprofile() != null && ...;单独判空再取值无防护作用;应封装为布尔方法复用;严禁使用非短路的&。

用短路与(&&)防止多级条件判定时的空指针异常,核心是把“判空”和“取值/调用”写在同一个表达式里,靠左侧为 false 时跳过右侧执行的特性,天然挡住后续危险操作。
逐层加守门人:用 && 串起访问链
访问深层结构(比如 user.getProfile().getAvatar().getUrl())时,不能只判最外层是否为空。必须每一步都作为前置条件参与判断:
user != null && user.getProfile() != null && user.getProfile().getAvatar() != null && user.getProfile().getAvatar().getUrl() != null- 只要其中任意一环为
null或false,后续所有方法都不会被调用 - 比嵌套 if 更紧凑,也比 try-catch 更轻量、语义更明确
把判空和取值锁在同一表达式里
短路保护只在表达式求值过程中生效,单独写判空再写取值,毫无防护作用:
- ✅ 安全:
if (user != null && "VIP".equals(user.getLevel()))——getLevel()只在user非空时才执行 - ❌ 危险:
if (user != null) { String level = user.getLevel(); ... }—— 若user.getLevel()内部返回null,后面用到level仍可能 NPE - ⚠️ 注意:
String url = user != null && user.getAvatar() != null ? user.getAvatar().getUrl() : null;是安全的;但user.getAvatar().getUrl()单独成行就失去保护
封装成布尔方法,兼顾复用与安全
把常用检查逻辑抽成返回 boolean 的方法,再用 && 组合,主流程依然干净且受保护:
private boolean hasValidAvatar(User user) { return user != null && user.getProfile() != null && user.getProfile().getAvatar() != null; }if (hasValidAvatar(user) && uploadAvatar(user.getProfile().getAvatar())) { ... }- 若
hasValidAvatar()返回false,uploadAvatar()根本不会执行
别误用 & 替代 &&
& 是位运算符(也用于布尔),它不短路,左右两边必定执行:
- ❌
if (user != null & user.isActive())—— 即使user是null,user.isActive()仍会被调用,直接抛 NPE - ✅ 必须用
&&,这是 Java、JavaScript、Go 等语言中实现空安全访问的通用约定











