代码优雅之道——Java如何判空

358e10c3772d6688b2724f804b784dcf.jpeg来源:juejin.cn/post/7224027867084292154

👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战/ Java 学习路线 / 一对一提问 / 学习打卡/  赠书福利

全栈前后端分离博客项目 1.0 版本完结啦,2.0 正在更新中...,全程手摸手,后端 + 前端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,直到项目上线。目前已更新了163小节,累计25w+字,讲解图:1105张,还在持续爆肝中.. 后续还会上新更多项目,目标是将Java领域典型的项目都整一波,如秒杀系统, 在线商城, IM即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,已有540+小伙伴加入(早鸟价超低)

  • 1 前言

  • 2 List的判空

  • 3 String的判空

  • 4 Optional

    • 4.1 Optional对象的创建

    • 4.2 使用场景

  • 5 总结


1 前言

实际项目中我们会有很多地方需要判空校验,如果不做判空校验则可能产生NullPointerException异常。

针对异常的处理我们在上一篇有提及:

先来看一下实际项目中一些判空方式

fb9f006edfc5d081af651623edebbfef.jpeg

图片

02dcbe074f8b436acb119d3e8c723f42.jpeg

图片

通常我们判断一个对象是否为Null,可以使用java.util中的Objects.nonNull(obj)、hutool中的ObjectUtil或者直接 null != obj

2 List的判空

像List这种比较特殊的在项目中可能不仅仅是判断非空了。对于List来说不等于null和List.size()不等于0是两回事,公司也有实习生常常有把这两个混淆的情况,list不等于null说明已经初始化了,堆内存中有一块属于它的地盘,而size为0说明还没往里面放东西,举个例子说就是不等于null代表我现在有个瓶子,size大于0说明我向瓶子里装水了。

实际项目中也发现有直接用list.isEmpty()去判断的,来看一下源码:

ac7935e244f6d9656515ef6fca43e1c9.jpeg

图片

相当于判断瓶子里有没有水(前提是瓶子已经存在,若瓶子不存在,则会抛出NullPointerException异常)。

所以通常情况下会连用list != null && list.size > 0 来判断,或者直接使用HuTool中CollUtil工具的isEmpty。诸如此类的还有Set、Map等

3 String的判空

这里还是用瓶子与水的概念,String为null时调用equals(String)length() 等操作抛出 java.lang.NullPointerException

e7dc3688501c6b3a04ceac556918a584.jpeg

图片

针对字符串判空有以下几种方式:

1、大多数人使用的方法之一,直观,方便,但效率低下:

if(a == null || a.equals(""));

2、比较字符串长度,高效:

if(a == null || a.length() == 0);

3、Java SE 6.0 才刚刚开始提供,效率和方法二差不多:

if(a == null || a.isEmpty());

当然还可以使用org.apache.commons.lang.StringUtils工具。

StringUtils.isNotBlank(a);

  • StringUtils.isNotBlank(null) = false

  • StringUtils.isNotBlank("") = false

  • StringUtils.isNotBlank(" ") = false

  • StringUtils.isNotBlank("bob") = true

  • StringUtils.isNotBlank(" bob ") = true

该工具类中还有个isNotEmpty()方法,从注释可以很明显看出二者的差别

StringUtils.isNotEmpty(a);

  • StringUtils.isNotEmpty(null) = false

  • StringUtils.isNotEmpty("") = false

  • StringUtils.isNotEmpty(" ") = true

  • StringUtils.isNotEmpty("bob") = true

  • StringUtils.isNotEmpty(" bob ") = true

4 Optional

Optional的出现就是用来防止NullpointException的。常见的方法有:

  • .empty() 创建一个空的Optional实例

  • .of(T t): 创建一个Optional 实例,为null时报异常

  • .ofNullable(T t): 若t 不为null,创建Optional 实例,否则创建空实例

  • isPresent(): 判断容器中是否有值

  • ifPresent(Consume lambda) 容器若不为空则执行括号中的Lambda表达式

  • orElse(T t): 获取容器中的元素,若容器为空则返回括号中的默认值

  • orElseGet(Supplier s): 如果调用对象包含值,返回该值,否则返回s 获取的值

  • orElseThrow(): 如果为空,就抛出定义的异常,如果不为空返回当前对象

  • map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()

  • flatMap(Function mapper): 与map 类似,要求返回值必须是Optional

  • T get() 获取容器中的元素,若容器为空则抛出NoSuchElement异常

先看个常见的示例:

baseInfo类中有布尔类型的属性,是空返回false,不为空取其值,需要四行。

ecd12f584959ac19f0b1ec57cd924970.jpeg

图片

当使用Optional时,一行搞定,非常的优雅。

1ab44c34cfb14487b1210ef92bc972d6.jpeg

图片

4.1 Optional对象的创建

public final class Optional<T> {
    private static final Optional<?> EMPTY = new Optional<>();
    private final T value;
    //可以看到两个构造方格都是private 私有的
    //说明 没办法在外面new出来Optional对象
    private Optional() {
        this.value = null;
    }
    private Optional(T value) {
        this.value = Objects.requireNonNull(value);
    }
    //这个静态方法大致 是创建出一个包装值为空的一个对象因为没有任何参数赋值
    public static<T> Optional<T> empty() {
        @SuppressWarnings("unchecked")
        Optional<T> t = (Optional<T>) EMPTY;
        return t;
    }
    //这个静态方法大致 是创建出一个包装值非空的一个对象 因为做了赋值
    public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
    }
    //这个静态方法大致是 如果参数value为空,则创建空对象,如果不为空,则创建有参对象
    public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
    }
}

4.2 使用场景

场景1:在service层中 查询一个对象,返回之后判断是否为空并做处理

08c7c15cf185996b75617d219aba2211.jpeg

图片

场景2:使用Optional 和函数式编程,一行搞定

d439f009fb525ec58b69bad8ca38bc09.jpeg

图片

5 总结

每种方法的存在必然有适用的场景,有些情况下这种链式编程,虽然代码优雅了。但是,逻辑性没那么明显,可读性有所降低,大家项目中看情况酌情使用。

👉 欢迎加入小哈的星球 ,你将获得: 专属的项目实战/ Java 学习路线 / 一对一提问 / 学习打卡/  赠书福利

全栈前后端分离博客项目 1.0 版本完结啦,2.0 正在更新中...,全程手摸手,后端 + 前端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,直到项目上线。目前已更新了163小节,累计25w+字,讲解图:1105张,还在持续爆肝中.. 后续还会上新更多项目,目标是将Java领域典型的项目都整一波,如秒杀系统, 在线商城, IM即时通讯,Spring Cloud Alibaba 等等,戳我加入学习,已有540+小伙伴加入(早鸟价超低)

 
 

0c06f0f6008ddbca29c054beb9da2279.jpeg

 
 
 
 
 
 
 
 
 
 

35b5da0b3be1eab9a336566fcede5605.gif

 
 
 
 
 
 

1. 我的私密学习小圈子~

2. 别再自己封装了,推荐一个功能强大的分布式锁框架:Lock4j

3. HTTPS 行为大赏:三分钟了解加密过程

4. 为什么阿里巴巴修正了HashMap关于1024个元素扩容的次数?

759a403015ae40b01c04211ef3ca1051.gif

最近面试BAT,整理一份面试资料《Java面试BATJ通关手册》,覆盖了Java核心技术、JVM、Java并发、SSM、微服务、数据库、数据结构等等。
获取方式:点“在看”,关注公众号并回复 Java 领取,更多内容陆续奉上。
PS:因公众号平台更改了推送规则,如果不想错过内容,记得读完点一下“在看”,加个“星标”,这样每次新文章推送才会第一时间出现在你的订阅列表里。
点“在看”支持小哈呀,谢谢啦
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值