Java 中防范 null 的核心是提前拦截而非事后判空:入参用 requireNonNull、字符串比较用常量左置或工具类、返回值用 Optional 明确语义、避免自动拆箱 NPE,并对外部依赖封装非 null 协议。

Java 中 if 条件判断为 null 本身不会出错,真正危险的是在判空前就调用了 null 对象的方法或属性——比如 str.length() 或 user.getAddress().getCity()。防范的关键不是“怎么写 if”,而是让 null 在进入业务逻辑前就被识别、拦截或转化。
入参和构造器:用 requireNonNull 主动拦住 null
对明确不该为 null 的参数,别等它走到 if 里再处理。在方法入口或构造函数中直接拦截,问题暴露得早、堆栈清晰、修复成本低。
- 写法示例:
Objects.requireNonNull(user, "用户信息不能为空") - 配合
@NonNull(Lombok 或 IntelliJ)能提前在编译期/IDE 层提示风险 - 避免在已有判空逻辑的 if 块里重复加 requireNonNull,造成冗余
字符串比较:常量左置或工具类兜底
写 status.equals("OK") 很自然,但 status 为 null 就炸;换成 "OK".equals(status) 安全又简洁。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 推荐统一用
StringUtils.isEmpty(str)(Apache Commons)或TextUtils.isEmpty(str)(Android),它们内部已处理 null - 避免手写
str == null || str.length() == 0,既啰嗦又易错序(必须先判 null,否则str.length()触发 NPE)
返回值不确定时:用 Optional 明确表达“可能为空”
Optional 不是给字段或参数用的,而是封装**方法返回语义**——告诉调用方:“这个结果可能没有,请按契约取值”。
立即学习“Java免费学习笔记(深入)”;
- 包装:数据库查询结果用
Optional.ofNullable(userDao.findById(id)) - 取值:优先用
opt.orElse("默认用户")或opt.orElseGet(this::fetchDefault) - 禁用写法:
opt.isPresent() && opt.get(),这等于绕开 Optional 的设计初衷
三元运算符与自动拆箱:警惕隐式类型转换
user != null ? user.getId() : 0 看似安全,但如果 getId() 返回的是 Integer,而接收变量是 int,null 分支会触发自动拆箱 → NPE。
- 正确写法:
Objects.requireNonNullElse(user, new User()).getId(),或显式处理包装类型:user != null ? user.getId() : null,再用Optional.ofNullable(id).orElse(0) - 远程调用、配置读取等外部依赖,应封装成非 null 协议(如返回空集合、空对象、带默认值的 DTO),从源头减少 null 暴露

















