如何与亦敌亦友的 null 说拜拜?大神原来是这么做的!

作者| 沉默王二

责编| Carol

封图| CSDN│下载于视觉中国

从 10 年前我开始写第一行 Java 代码至今,一直觉得 null 在 Java 中是一个最特殊的存在,它既是好朋友,可以把不需要的变量置为 null 从而释放内存,提高性能;它又是敌人,因为它和大名鼎鼎且烦不胜烦的 NullPointerException(NPE)如影随形,而 NPE 的发明人 Tony Hoare 曾在 2009 年承认:“Null References 是一个荒唐的设计,就好像我赌输掉了十亿美元”。

你看,null 竟然是一个亦敌亦友的家伙。

通常,为了表示列表中的元素不存在,我们首先想到的就是返回 null,这种想法很合理,合理到无法反驳。我们来模拟一个实际的应用场景,假设作者现在要从数据库中获取一个姓名的列表,然后将姓名打印到控制台,对应的代码如下。

public class NullDemo {public static void main(String[] args) {List<String> names = getNamesFromDB();if (names != null) {for (String name : names) {System.out.println(name);}}}public static List<String> getNamesFromDB() {// 模拟此时没有从数据库获取到对应的姓名。return null;}
}

由于 getNamesFromDB() 方法返回了 null 来作为没有姓名列表的标志,那就意味着在遍历列表的时候要先对列表判空,否则将会抛出 NPE 错误,不信你把 if (names != null) 去掉试试,立马给你颜色看。

Exception in thread "main" java.lang.NullPointerExceptionat com.cmower.dzone.stopdoing3things.NullDemo.main(NullDemo.java:12)

那假如作者在遍历的时候不想判空又不想代码抛出 NPE 错误,他该怎么做呢?闭上你的大眼睛好好想一想。

嗯,报告,我想出来了,建议作者从数据库中获取姓名的时候返回长度为 0 的列表,来表示未找到数据的情况。代码示例如下所示:

public class Null2Length0Demo {public static void main(String[] args) {List<String> names = getNamesFromDB();for (String name : names) {System.out.println(name);}}public static List<String> getNamesFromDB() {// 模拟此时没有从数据库获取到对应的姓名。return Collections.emptyList();}
}

注:Collections.emptyList() 用于返回一个不可变的空列表,能理解吧?假如不能理解的话,我再写一个返回可变的空列表的示例,你对比着感受一下就理解了。

public class Null2Length0MutableDemo {public static void main(String[] args) {List<String> names = getNamesFromDB();for (String name : names) {System.out.println(name);}}public static List<String> getNamesFromDB() {// 模拟此时没有从数据库获取到对应的姓名。return new ArrayList<>();}
}

new ArrayList<>() 返回的就是可变的,意味着你还可以改变这个列表的元素,比如说增加,删除是不可能的了,因为本身就没有元素可删。

你看,Collections.emptyList() 和 new ArrayList<>() 都可以替代 null,来减少打印列表时不必要的判空以及那个讨厌的家伙——NPE。

除了我这个想法之外,你还能想到其他的解决方案吗?来,再次闭上你的大眼睛,替作者想一想,没准你还能想到一个—— Java 8 新增的 Optional 类,一个容器类,可以存放任意类型的元素,如果值存在则
isPresent() 方法会返回 true;Optional 类提供了很多专业的方法而不用显式进行空值检查,从而巧妙地消除了 NPE。

来,先读示例为快!

public class Null2OptionalDemo {public static void main(String[] args) {Optional<List<String>> list = getNamesFromDB();list.ifPresent(names -> {for (String name : names) {System.out.println(name);}});}public static Optional<List<String>> getNamesFromDB() {boolean hasName = true;if (hasName) {String [] names = {"沉默王二", "一枚有趣的程序员", "微信搜索关注我"};return Optional.of(Arrays.asList(names));}return Optional.empty();}
}

看得不太懂?我来负责任地介绍一下,你们握个手。

假如数据库中存在姓名,则使用 Optional.of() 对返回值进行包装,从而返回一个 Optional 类型的对象。为什么不用构造方法呢,因为构造方法是 private 的(源码如下所示)。

private Optional(T value) {this.value = value;
}

那为什么要用 Optional.of() 呢?嗯,good question。继续上源码。

public static <T> Optional<T> of(T value) {return new Optional<>(Objects.requireNonNull(value));
}

1)如果 value 为 null,那么 Objects.requireNonNull(value) 就会抛出 NPE(嗯哼,总归是要碰面的,但好歹不用我们程序员主动 check 了)。

2)如果 value 不为 null,则通过 new 关键字创建正常的 Optional 对象。

假如数据库中不存在姓名呢?使用 Optional.empty() 作为返回值。来,继续上源码。

public static<T> Optional<T> empty() {@SuppressWarnings("unchecked")Optional<T> t = (Optional<T>) EMPTY;return t;
}

嗯哼,EMPTY 是什么玩意?

private static final Optional<?> EMPTY = new Optional<>(null);

竟然是 Optional 类的一个私有常量(static + final)。怎么此刻我的脑子里想起了安徒生先生的寓言故事——皇帝的新衣,嗯,甭管了,反正“底层终究是丑陋的”。

这样的话,就可以使用 Optional 对象的 ifPresent() 方法来判断值是否存在,如果只需要处理值存在的情况,就可以使用 Lambda 表达式的方式直接打印姓名。

list.ifPresent(names -> {for (String name : names) {System.out.println(name);}
});

有点简单粗暴,对不对?但不管怎么说,终于可以在表象上和 null,NPE 说拜拜了,做人嘛,开心点~

如果你有其他想法,欢迎在评论区和我们交流!

《原力计划【第二季】- 学习力挑战》正式开始!即日起至 3月21日,千万流量支持原创作者!更有专属【勋章】等你来挑战

推荐阅读:不看就亏系列!这里有完整的 Hadoop 集群搭建教程,和最易懂的 Hadoop 概念!| 附代码
时间复杂度的表示、分析、计算方法……一文带你看懂时间复杂度!
30万行数据,Python 分析科比二十年职业生涯 | 原力计划
谈论新型冠状病毒、比特币、苹果公司……沃伦•巴菲特受访中的 18 个金句,值得一看!
一张图对比阿里、腾讯复工的区别
Python数据清理终极指南(2020版)
真香,朕在看了!

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

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

相关文章

K8s中Pod健康检查源代码分析

了解k8s中的Liveness和Readiness Liveness: 表明是否容器正在运行。如果liveness探测为fail&#xff0c;则kubelet会kill掉容器&#xff0c;并且会触发restart设置的策略。默认不设置的情况下&#xff0c;该状态为success. Readiness: 表明容器是否可以接受服务请求。如果re…

CSE:阿里在线应用如何演进成Serverless架构

Cloud Service Engine&#xff0c;简称CSE&#xff0c;是中间件部门研发的面向通用Serverless计算的中间件产品&#xff0c;目标是具备AWS Lambda的各种优势&#xff0c;同时可以解决AWS Lambda的关键技术缺陷。 AWS Lambda如果用于核心业务&#xff0c;可能会有以下缺陷&…

郫都区计算机学校,成都郫县好升学的计算机学校有哪些

【郫县好一、成都郫县希望1.成都郫县希望职业学校/招生代码&#xff1a;512632.成都郫县希望职业学校/学校简介&#xff1a;成都郫县希望职业学校学校是由郫都区教育局批准成立的&#xff0c;由希望集团投资创办的一所全日制、专业化的民办中等职业学校, 由郫都区教育局主管。学…

技术大佬:今年还学Python,傻了吧? 网友:就你敢说!

随着AI的兴起&#xff0c;Python彻底火了。据Stack Overflow调研报告&#xff1a;Python的月活用户已超越了Java、成为第一&#xff0c;全民Python已为“大势所趋”。那么&#xff0c;程序员有必要追捧Python吗&#xff1f;Python的真香是真香吗&#xff1f;技术大佬&#xff1…

基于Tablestore的Wifi设备监管系统架构实现

Wifi设备监管 某知名跨国公司&#xff0c;在全球范围内拥有大量园区&#xff0c;园区内会有不同部门的同事在一起办公。每个园区内都要配备大量的Wifi设备从而为园区同事提供方便的上网服务。因此&#xff0c;集团需要一套完善的监管系统维护所有的Wifi设备。 公司通过监管系…

聊聊安卓折叠屏给交互设计和开发带来的变化

很多年前&#xff0c;前端同学都觉得PC端的适配&#xff08;兼容处理&#xff09;难&#xff0c;都认为移动端的时代适配会容易得多&#xff0c;也无需考虑那么多的事情。事实并非如此&#xff0c;移动端的时代同样面临着各种适配的处理。特别是刘海机的出现&#xff0c;前端需…

你以为这样写代码很6,但我看不懂

来源 | 沉默王二责编| Carol封图| CSDN│下载于视觉中国为了提高 Java 编程的技艺&#xff0c;作者最近在 GitHub 上学习一些高手编写的代码。下面这一行代码&#xff08;出自大牛之手&#xff09;据说可以征服你的朋友&#xff0c;让他们觉得你写的代码很 6&#xff0c;来欣赏…

在闲鱼,我们如何用Dart做高效后端开发?

背景 像阿里其他技术团队以及业界的做法一样&#xff0c;闲鱼的大多数后端应用都是全部使用java来实现的。java易用、丰富的库、结构容易设计的特性决定了它是进行业务开发的最好语言之一。后端应用中数据的存储、访问、转换、输出虽然都属于后端的范畴&#xff0c;但是其中变…

解决 mysql>com.mysql.jdbc.PacketTooBigException: Packet for query is too large (12073681 > 4194304)

com.mysql.jdbc.PacketTooBigException: Packet for query is too large 异常解决办法&#xff1a; 原因&#xff1a; 查询出的数据包过大&#xff0c;默认情况下mysql 的字段容量不够装&#xff0c;所以抛出此异常 解决办法&#xff1a; 第一步&#xff1a;首先通过SQLyog客…

MySQL数据库无完整备份删库,除了跑路还能怎么办?

来源 | 阿丸笔记责编| Carol封图| CSDN│下载于视觉中国“删库跑路”这个词儿&#xff0c;经常被挂在嘴边当玩笑&#xff0c;是因为大家都知道&#xff0c;一旦真的发生这样的事情&#xff0c;企业损失是无比惨重的。本文作者为 CSDN 博客的一位博主&#xff0c; 从他的描述中得…

区块链和大数据一起能否开启数据完整性的新纪元?

作者 | Vijay Singh Khatri译者 | 天道酬勤 责编 | 徐威龙封图| CSDN 下载于视觉中国每当提到区块链一词时&#xff0c;许多人都会将其与比特币等加密货币联系起来。这项技术通过加快交易速度、提供隐私和透明以及其他更多功能&#xff0c;确实改变了虚拟货币的世界。但是&…

带出7个“师弟”,支付宝BASIC College的辅导员是个伪90后

“我的花名是改之&#xff0c;不是‘有则改之无则加勉’的改之&#xff0c;而是‘杨过&#xff0c;字改之’的那个改之。”一见面&#xff0c;他对自己花名的介绍&#xff0c;就让人耳目一新。至于为什么要用杨过的字给自己起名&#xff0c;他也毫不扭捏地坦诚相告&#xff1a;…

整理了Kafka的一些常用工具,建议收藏备用!| 博文精选

作者 | 犀牛饲养员责编 | 徐威龙封面付费下载于视觉中国本文主要列举一些 Kafka 的常用工具&#xff0c;以及举了一些例子来帮助理解。有需要的小伙伴&#xff0c;可以 Mark 起来再看。环境以下的操作都是基于kafka_2.11-2.2.0工具新建topicbin/kafka-topics.sh --create --zoo…

阿里的初感知

很荣幸能加入阿里这个大家庭&#xff0c;在这短短的一个月里&#xff0c;阿里的一些不同让我印象深刻。 owner精神 入职第一天&#xff0c;上午进行了合同签订和简单的入职培训&#xff0c;下午就领了电脑设备到了办公区。 在电梯里&#xff0c;恰巧遇到了面试过我的同学&…

两大图灵奖得主点赞中国用AI检测新冠,AI还能做什么?

作者 | CV君来源 | 我爱计算机视觉封图| CSDN│下载于视觉中国在这次新冠肺炎疫情肆虐的时候&#xff0c;AI 成为对抗疫情的亮点&#xff0c;前几天两大图灵奖得主 Yoshua Bengio 和 Yann LeCun 在对比中美两国面对疫情处理时&#xff0c;特别点赞了我国企业使用深度学习检测新…

首次披露!阿里线下智能方案进化史

阿里妹导读&#xff1a;AI 技术已经从互联网走向零售、汽车、银行等传统行业。受限于延时、成本、安全等多方面的限制&#xff0c;单一的云解决方案往往不能满足场景需求。线下智能方案逐步成为了智能化过程中重要的一环&#xff0c;今天&#xff0c;我们就一起来了解这一环&am…

同方服务器操作系统安装,同方云服务器安装使用手册

同方云服务器安装使用手册 内容精选换一换制作Docker镜像&#xff0c;有以下两种方法。快照方式制作镜像(偶尔制作的镜像)&#xff1a;在基础镜像上&#xff0c;比如Ubuntu&#xff0c;先登录镜像系统并安装Docker软件&#xff0c;然后整体制作快照&#xff0c;即可得到所需软件…

蚂蚁金服面对亿级并发场景的组件体系设计

5 月 6 日&#xff0c;InfoQ 主办的 QCon 2019 全球软件开发大会在北京举行。蚂蚁金服技术专家吕丹&#xff08;凝睇&#xff09;在大会上做了《蚂蚁金服面对亿级并发场景的组件体系设计》的分享&#xff0c;我们根据演讲整理如下&#xff1a; 今天&#xff0c;我主要想和大家…

聚焦效率与目标差距,数据才是远程办公的内核!

作者&#xff5c;帆软数据应用研究院 新冠肺炎疫情将远程办公推向了春节后的热度高峰&#xff0c;引爆了远程移动办公应用市场。在“不出门&#xff0c;不聚集”的战疫要求下&#xff0c;远程办公成为企业减小损失、复工过渡的首选。 然而在众多企业如火如荼开展远程办公的同…

“大团队”和“敏捷开发”,谁说不可兼得?

阿里妹导读&#xff1a;当小团队的产出跟不上业务需要&#xff0c;团队就面临规模化的问题。从1个团队到3个团队&#xff0c;仍可以通过简单的团队沟通保持高效协作。当产品复杂到需要5个以上团队同时开发时&#xff0c;我们需要一定的组织设计来保证团队间的顺畅协作&#xff…