Objects.requireNonNull并非万能解药,它仅适用于绝对不可为null的边界输入;对合法语义空应使用Optional封装或明确文档标注,而非强制抛异常。
Java中Objects.requireNonNull为何不是万能解药
它确实能快速暴露null,但前提是调用方主动加——这在深层调用链、第三方库返回值、或配置未加载完成的场景下根本不可控。比如service.findUser(id)返回null,你没在入口校验,下游直接user.getName()就NPE了。
更关键的是,它把“空值处理逻辑”推给了调用方,而实际业务里,很多null是合法状态(如用户未填地址),强制抛异常反而破坏流程。真正要做的,是区分「非法空」和「语义空」。
-
requireNonNull适合构造函数参数、必填配置项等绝对不允许为null的边界输入 - 对可能为空的返回值,优先用
Optional封装,而非裸null - 若必须返回
null(如遗留接口),应在Javadoc明确标注@return may be null
用Optional替代null返回值的实操陷阱
Optional本意是让空值显式化,但滥用会导致嵌套地狱或误用get()重蹈NPE覆辙。例如userRepo.findById(123).get().getProfile().getEmail()——只要中间任一环节是Optional.empty(),get()立刻炸。
正确姿势是链式消费:用map、flatMap、orElse把逻辑写在Optional内部,而不是把它当容器取出来再操作。
立即学习“Java免费学习笔记(深入)”;
- 不要用
Optional包装集合或数组(该用Collections.emptyList()) - 不要将
Optional作为方法参数或字段(违背其设计初衷) - 数据库查询结果为空时,用
Optional.ofNullable(result)包装,而非直接返回null
静态工具类Objects.nonNull和Objects.isNull的真实用途
它们只是简洁的判空工具,不解决根本问题。常见误用是写成if (Objects.nonNull(user)) { user.getName(); }——这跟if (user != null)没区别,只是多了一层方法调用开销。