瞧瞧别人家的判空,那叫一个优雅!

一、传统判空的血泪史

某互联网金融平台因费用计算层级的空指针异常,导致凌晨产生9800笔错误交易。

DEBUG日志显示问题出现在如下代码段:

csharp

体验AI代码助手

代码解读

复制代码

// 错误示例 BigDecimal amount = user.getWallet().getBalance().add(new BigDecimal("100"));

此类链式调用若中间环节出现null值,必定导致NPE。

初级阶段开发者通常写出多层嵌套式判断:

scss

体验AI代码助手

代码解读

复制代码

if(user != null){ Wallet wallet = user.getWallet(); if(wallet != null){ BigDecimal balance = wallet.getBalance(); if(balance != null){ // 实际业务逻辑 } } }

这种写法既不优雅又影响代码可读性。

那么,我们该如何优化呢?

二、Java 8+时代的判空革命

Java8之后,新增了Optional类,它是用来专门判空的。

能够帮你写出更加优雅的代码。

1. Optional黄金三板斧

css

体验AI代码助手

代码解读

复制代码

// 重构后的链式调用 BigDecimal result = Optional.ofNullable(user) .map(User::getWallet) .map(Wallet::getBalance) .map(balance -> balance.add(new BigDecimal("100"))) .orElse(BigDecimal.ZERO);

高级用法:条件过滤

scss

体验AI代码助手

代码解读

复制代码

Optional.ofNullable(user) .filter(u -> u.getVipLevel() > 3) .ifPresent(u -> sendCoupon(u)); // VIP用户发券

2. Optional抛出业务异常

scss

体验AI代码助手

代码解读

复制代码

BigDecimal balance = Optional.ofNullable(user) .map(User::getWallet) .map(Wallet::getBalance) .orElseThrow(() -> new BusinessException("用户钱包数据异常"));

3. 封装通用工具类

typescript

体验AI代码助手

代码解读

复制代码

public class NullSafe { // 安全获取对象属性 public static <T, R> R get(T target, Function<T, R> mapper, R defaultValue) { return target != null ? mapper.apply(target) : defaultValue; } // 链式安全操作 public static <T> T execute(T root, Consumer<T> consumer) { if (root != null) { consumer.accept(root); } return root; } } // 使用示例 NullSafe.execute(user, u -> { u.getWallet().charge(new BigDecimal("50")); logger.info("用户{}已充值", u.getId()); });

三、现代化框架的判空银弹

4. Spring实战技巧

Spring中自带了一些好用的工具类,比如:CollectionUtils、StringUtils等,可以非常有效的进行判空。

具体代码如下:

scss

体验AI代码助手

代码解读

复制代码

// 集合判空工具 List<Order> orders = getPendingOrders(); if (CollectionUtils.isEmpty(orders)) { return Result.error("无待处理订单"); } // 字符串检查 String input = request.getParam("token"); if (StringUtils.hasText(input)) { validateToken(input); }

5. Lombok保驾护航

我们在日常开发中的entity对象,一般会使用Lombok框架中的注解,来实现getter/setter方法。

其实,这个框架中也提供了@NonNull等判空的注解。

比如:

less

体验AI代码助手

代码解读

复制代码

@Getter @Setter public class User { @NonNull // 编译时生成null检查代码 private String name; private Wallet wallet; } // 使用构造时自动判空 User user = new User(@NonNull "张三", wallet);

四、工程级解决方案

6. 空对象模式

typescript

体验AI代码助手

代码解读

复制代码

public interface Notification { void send(String message); } // 真实实现 public class EmailNotification implements Notification { @Override public void send(String message) { // 发送邮件逻辑 } } // 空对象实现 public class NullNotification implements Notification { @Override public void send(String message) { // 默认处理 } } // 使用示例 Notification notifier = getNotifier(); notifier.send("系统提醒"); // 无需判空

7. Guava的Optional增强

其实Guava工具包中,给我们提供了Optional增强的功能。

比如:

ini

体验AI代码助手

代码解读

复制代码

import com.google.common.base.Optional; // 创建携带缺省值的Optional Optional<User> userOpt = Optional.fromNullable(user).or(defaultUser); // 链式操作配合Function Optional<BigDecimal> amount = userOpt.transform(u -> u.getWallet()) .transform(w -> w.getBalance());

Guava工具包中的Optional类已经封装好了,我们可以直接使用。

五、防御式编程进阶

8. Assert断言式拦截

其实有些Assert断言类中,已经做好了判空的工作,参数为空则会抛出异常。

这样我们就可以直接调用这个断言类。

例如下面的ValidateUtils类中的requireNonNull方法,由于它内容已经判空了,因此,在其他地方调用requireNonNull方法时,如果为空,则会直接抛异常。

我们在业务代码中,直接调用requireNonNull即可,不用写额外的判空逻辑。

例如:

typescript

体验AI代码助手

代码解读

复制代码

public class ValidateUtils { public static <T> T requireNonNull(T obj, String message) { if (obj == null) { throw new ServiceException(message); } return obj; } } // 使用姿势 User currentUser = ValidateUtils.requireNonNull( userDao.findById(userId), "用户不存在-ID:" + userId );

最近就业形势比较困难,为了感谢各位小伙伴对苏三一直以来的支持,我特地创建了一些工作内推群, 看看能不能帮助到大家。

你可以在群里发布招聘信息,也可以内推工作,也可以在群里投递简历找工作,也可以在群里交流面试或者工作的话题。

添加苏三的私人微信:li_su223,备注:掘金+所在城市,即可加入。

9. 全局AOP拦截

我们在一些特殊的业务场景种,可以通过自定义注解 + 全局AOP拦截器的方式,来实现实体或者字段的判空。

例如:

less

体验AI代码助手

代码解读

复制代码

@Aspect @Component public class NullCheckAspect { @Around("@annotation(com.xxx.NullCheck)") public Object checkNull(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); for (Object arg : args) { if (arg == null) { throw new IllegalArgumentException("参数不可为空"); } } return joinPoint.proceed(); } } // 注解使用 public void updateUser(@NullCheck User user) { // 方法实现 }

六、实战场景对比分析

场景1:深层次对象取值

scss

体验AI代码助手

代码解读

复制代码

// 旧代码(4层嵌套判断) if (order != null) { User user = order.getUser(); if (user != null) { Address address = user.getAddress(); if (address != null) { String city = address.getCity(); // 使用city } } } // 重构后(流畅链式) String city = Optional.ofNullable(order) .map(Order::getUser) .map(User::getAddress) .map(Address::getCity) .orElse("未知城市");

场景2:批量数据处理

scss

体验AI代码助手

代码解读

复制代码

List<User> users = userService.listUsers(); // 传统写法(显式迭代判断) List<String> names = new ArrayList<>(); for (User user : users) { if (user != null && user.getName() != null) { names.add(user.getName()); } } // Stream优化版 List<String> nameList = users.stream() .filter(Objects::nonNull) .map(User::getName) .filter(Objects::nonNull) .collect(Collectors.toList());

七、性能与安全的平衡艺术

上面介绍的这些方案都可以使用,但除了代码的可读性之外,我们还需要考虑一下性能因素。

下面列出了上面的几种在CPU消耗、内存只用和代码可读性的对比:

方案CPU消耗内存占用代码可读性适用场景
多层if嵌套★☆☆☆☆简单层级调用
Java Optional★★★★☆中等复杂度业务流
空对象模式★★★★★高频调用的基础服务
AOP全局拦截★★★☆☆接口参数非空验证

黄金法则

  • Web层入口强制参数校验
  • Service层使用Optional链式处理
  • 核心领域模型采用空对象模式

八、扩展技术

除了,上面介绍的常规判空之外,下面再给大家介绍两种扩展的技术。

Kotlin的空安全设计

虽然Java开发者无法直接使用,但可借鉴其设计哲学:

ini

体验AI代码助手

代码解读

复制代码

val city = order?.user?.address?.city ?: "default"

JDK 14新特性预览

less

体验AI代码助手

代码解读

复制代码

// 模式匹配语法尝鲜 if (user instanceof User u && u.getName() != null) { System.out.println(u.getName().toUpperCase()); }

总之,优雅判空不仅是代码之美,更是生产安全底线。

本文分享了代码判空的10种方案,希望能够帮助你编写出既优雅又健壮的Java代码。

最后说一句(求关注,别白嫖我)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/1184652.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全毕设本科生方向集合

0 选题推荐 - 云计算篇 毕业设计是大家学习生涯的最重要的里程碑&#xff0c;它不仅是对四年所学知识的综合运用&#xff0c;更是展示个人技术能力和创新思维的重要过程。选择一个合适的毕业设计题目至关重要&#xff0c;它应该既能体现你的专业能力&#xff0c;又能满足实际应…

详细介绍:C#中常见集合都有哪些?

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

职场必备!ima知识库+AI,让你的收藏夹变成生产力神器

文章介绍了ima知识库工具&#xff0c;通过AI技术重新定义知识的收集、管理、应用和分享。用户可多渠道收集信息&#xff0c;AI自动整理生成摘要&#xff0c;智能问答辅助决策创作&#xff0c;支持团队协作共享。文章提供了PC端和手机端的使用技巧&#xff0c;帮助用户建立标签体…

网络安全毕设简单的项目选题思路

0 选题推荐 - 云计算篇 毕业设计是大家学习生涯的最重要的里程碑&#xff0c;它不仅是对四年所学知识的综合运用&#xff0c;更是展示个人技术能力和创新思维的重要过程。选择一个合适的毕业设计题目至关重要&#xff0c;它应该既能体现你的专业能力&#xff0c;又能满足实际应…

收藏!AI替代IT团队?资深技术人深度解析行业变革与未来出路

AI技术崛起导致全球IT行业裁员潮&#xff0c;传统IT面临四重冲击&#xff1a;AI效率革命、企业战略转移、经济成本重构、人才需求转变。IT从业者需通过三条路径进化&#xff1a;能力重构从工具掌握到思维升级、定位转换从技术支持到价值创造、人机协作从替代焦虑到增强信心。不…

如何利用类似谷歌搜索文献的方式高效查找学术资源与研究资料

做科研的第一道坎&#xff0c;往往不是做实验&#xff0c;也不是写论文&#xff0c;而是——找文献。 很多新手科研小白会陷入一个怪圈&#xff1a;在知网、Google Scholar 上不断换关键词&#xff0c;结果要么信息过载&#xff0c;要么完全抓不到重点。今天分享几个长期使用的…

免费文献检索网站:实用资源推荐与高效使用指南

做科研的第一道坎&#xff0c;往往不是做实验&#xff0c;也不是写论文&#xff0c;而是——找文献。 很多新手科研小白会陷入一个怪圈&#xff1a;在知网、Google Scholar 上不断换关键词&#xff0c;结果要么信息过载&#xff0c;要么完全抓不到重点。今天分享几个长期使用的…

xactengine2_9.dll文件丢失找不到问题 免费下载方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

【CSO MTSP】基于matlab自适应双种群协同鸡群算法ADPCCSO求解单仓库多旅行商问题【含Matlab源码 14998期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;欢迎来到海神之光博客之家&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49…

没有转化体系的物种,如何研究其基因功能?(四)

伯小远在“没有转化体系的物种&#xff0c;如何研究其基因功能&#xff08;一&#xff09;”中重点写了有稳定转化体系的物种的基因功能研究套路总结&#xff0c;在“&#xff08;二&#xff09;”中主要写了有哪些瞬时转化体系大家可以考虑使用&#xff0c;在“&#xff08;三…

当系统出现xactengine2_7.dll文件丢失找不到问题 免费下载方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

【六翼旋翼机】六翼旋翼机运输悬挂有效载荷的建模与控制【含Matlab源码 15000期】

&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;&#x1f49e;Matlab领域博客之家&#x1f49e;&…

Planning vs ReAct大对决:智能体架构终极指南,一篇收藏够用!附完整代码实现与性能评测

Planning架构是一种前瞻性决策的智能体设计模式&#xff0c;与ReAct"边走边看"不同&#xff0c;它先规划后执行。由Planner(规划)、Executor(执行)和Synthesizer(综合)三组件组成&#xff0c;遵循"接受任务→创建计划→执行计划→合成结果"流程。优点是结构…

AI Agent技术全景扫盲:从LLM到多智能体协作,一篇看懂核心概念

一、什么是AI Agent&#xff1f;AI Agent&#xff08;人工智能智能体&#xff09;是一个能够感知环境、做出决策、执行行动的智能系统。它不是被动等待输入的传统AI程序&#xff0c;而是具备"自主规划能力"的主动智能体。与传统AI最大的区别在于&#xff1a;传统AI是…

xactengine3_5.dll文件丢失找不到问题 免费下载方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

2026必备!MBA论文写作TOP9 AI论文平台深度测评

2026必备&#xff01;MBA论文写作TOP9 AI论文平台深度测评 2026年MBA论文写作工具测评&#xff1a;如何选择高效可靠的AI平台 随着人工智能技术的不断进步&#xff0c;越来越多的MBA学生开始借助AI论文平台提升写作效率。然而&#xff0c;面对市场上种类繁多的工具&#xff0c;…

xactengine2_10.dll文件丢失找不到问题 免费下载方法分享

在使用电脑系统时经常会出现丢失找不到某些文件的情况&#xff0c;由于很多常用软件都是采用 Microsoft Visual Studio 编写的&#xff0c;所以这类软件的运行需要依赖微软Visual C运行库&#xff0c;比如像 QQ、迅雷、Adobe 软件等等&#xff0c;如果没有安装VC运行库或者安装…

【必看收藏】AI时代程序员生死劫:从“制造者“到“顾问“的思维大转变,不看就落后!

AI时代下&#xff0c;程序员正经历从"制造者"到"顾问"的根本性转变。代码生产成本趋近于零&#xff0c;而有价值的思考和沟通变得稀缺。未来程序员的核心价值不再是执行清晰任务&#xff0c;而是在模糊需求中主动挖掘上下文&#xff0c;理解并解决真正问题…

藏在新丰江的野趣秘境!漂流溯溪玩转河源野趣沟

位于广东省河源市源城区大桂山主峰北部的野趣沟旅游区&#xff0c;是一处以“野趣”为核心主题的自然生态景区。它毗邻万绿湖&#xff0c;地处新丰江国家森林公园范围内&#xff0c;总面积约5至8平方公里。景区内古藤巨树遮天蔽日&#xff0c;飞瀑流泉层叠分布&#xff0c;形成…

大模型时代的程序员悖论:如何避免被AI取代?收藏这篇就够了

文章探讨了AI时代程序员如何保持竞争力。AI是杠杆而非替代品&#xff0c;会放大人的判断力或错误。程序员需建立判断力&#xff0c;采用三层思考法&#xff08;先独立思考&#xff0c;再用AI验证&#xff0c;最后深度内化&#xff09;&#xff0c;区分核心与边缘技能&#xff0…