Java8特性解决空指针问题

在文章的开头,先说下NPE问题,NPE问题就是,我们在开发中经常碰到的NullPointerException.假设我们有两个类,他们的UML类图如下图所示:

在这种情况下,有如下代码

这种写法,在user为null时,是有可能报NullPointerException异常的。为了解决这个问题,于是采用下面的写法

这种写法是比较丑陋的,为了避免上述丑陋的写法,让丑陋的设计变得优雅。JAVA8提供了Optional类来优化这种写法,接下来的正文部分进行详细说明。

API介绍

先介绍一下API,与其他文章不同的是,本文采取类比的方式来讲,同时结合源码。而不像其他文章一样,一个个API罗列出来,让人找不到重点。

(1)Optional(T value),empty(),of(T value),ofNullable(T value)

这四个函数之间具有相关性,因此放在一组进行记忆。

先说明一下,Optional(T value),即构造函数,它是private权限的,不能由外部调用的。其余三个函数是public权限,供我们所调用。那么,Optional的本质,就是内部储存了一个真实的值,在构造的时候,就直接判断其值是否为空。好吧,这么说还是比较抽象。直接上Optional(T value)构造函数的源码,如下图所示:

那么,of(T value)的源码如下:

也就是说of(T value)函数内部调用了构造函数。根据构造函数的源码我们可以得出两个结论:

(1)通过of(T value)函数所构造出的Optional对象,当Value值为空时,依然会报NullPointerException。

(2)通过of(T value)函数所构造出的Optional对象,当Value值不为空时,能正常构造Optional对象。

除此之外呢,Optional类内部还维护一个value为null的对象,大概就是长下面这样的

那么,empty()的作用就是返回EMPTY对象。

好了铺垫了这么多,可以说ofNullable(T value)的作用了,上源码

好吧,大家应该都看得懂什么意思了。相比较of(T value)的区别就是,当value值为null时,of(T value)会报NullPointerException异常;ofNullable(T value)不会throw Exception,ofNullable(T value)直接返回一个EMPTY对象。

那是不是意味着,我们在项目中只用ofNullable函数而不用of函数呢?

不是的,一个东西存在那么自然有存在的价值。当我们在运行过程中,不想隐藏NullPointerException。而是要立即报告,这种情况下就用Of函数。但是不得不承认,这样的场景真的很少。博主也仅在写junit测试用例中用到过此函数。

(2)orElse(T other),orElseGet(Supplier other)和orElseThrow(SupplierexceptionSupplier)

这三个函数放一组进行记忆,都是在构造函数传入的value值为null时,进行调用的。orElse和orElseGet的用法如下所示,相当于value值为null时,给予一个默认值:

这两个函数的区别:当user值不为null时,orElse函数依然会执行createUser()方法,而orElseGet函数并不会执行createUser()方法,大家可自行测试。

至于orElseThrow,就是value值为null时,直接抛一个异常出去,用法如下所示

(3) map(Function mapper)和flatMap(Function> mapper)

这两个函数放在一组记忆,这两个函数做的是转换值的操作。

直接上源码:

这两个函数,在函数体上没什么区别。唯一区别的就是入参,map函数所接受的入参类型为Function,而flapMap的入参类型为Function>。

在具体用法上,对于map而言:

如果User结构是下面这样的

这时候取name的写法如下所示:

对于flatMap而言:

如果User结构是下面这样的

这时候取name的写法如下所示

(4) isPresent()和ifPresent(Consumer consumer)

这两个函数放在一起记忆,isPresent即判断value值是否为空,而ifPresent就是在value值不为空时,做一些操作。这两个函数的源码如下

需要额外说明的是,大家千万不要把

给写成

因为这样写,代码结构依然丑陋。博主会在后面给出正确写法

至于ifPresent(Consumer consumer),用法也很简单,如下所示

(5) filter(Predicate predicate)

不多说,直接上源码

filter 方法接受一个 Predicate 来对 Optional 中包含的值进行过滤,如果包含的值满足条件,那么还是返回这个 Optional;否则返回 Optional.empty。

用法如下:

Optional user1 = Optional.ofNullable(user).filter(u -> u.getName().length()<6);

如上所示,如果user的name的长度是小于6的,则返回。如果是大于6的,则返回一个EMPTY对象。

实战使用例一

在函数方法中

以前写法

JAVA8写法

例二

比如,在主程序中

以前写法

JAVA8写法

例三

以前写法

java8写法

其他的例子,不一一列举了。不过,博主认为,其实采用这种链式编程,虽然代码优雅了。但是,逻辑性没那么明显,可读性有所降低,大家项目中看情况酌情使用。

 为了让学习变得轻松、高效,今天给大家免费分享一套Java教学资源。帮助大家在成为Java架构师的道路上披荆斩棘。需要资料的欢迎加入学习交流群:9285,05736

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

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

相关文章

模拟进程创建、终止、阻塞、唤醒原语_操作系统第二章--进程的描述与控制

操作系统第二章--进程的描述与控制前趋图和程序执行前趋图前趋图是一个有向无循环图DAG&#xff0c;用来描述进程之间执行的前后关系初始结点&#xff1a;没有前趋的结点终止结点&#xff1a;没有后继的结点重量&#xff1a;表示该结点所含有的程序量或结点的执行时间程序执行顺…

python变量声明语句_python – 在条件语句中声明变量有问题吗?

在条件的所有可能分支中重新定义变量之前,它是否可以防止定义变量&#xff1f;比如应该这个代码&#xff1a;# Condition could failtry:textureIndices someExpression()# textureIndices is defined here if it doesexcept:textureIndices []return textureIndices重写为&a…

Java单例模式的七种写法

第一种&#xff08;懒汉&#xff0c;线程不安全&#xff09;&#xff1a; public class Singleton { private static Singleton instance; private Singleton (){} public static Singleton getInstance() { if (instance null) { instance new Singleton(); } retur…

css3正方体选中父层 子层解体_CSS3 :nth-child(n)选择器 匹配属于其父元素的第N个子元素...

定义和用法:nth-child(n) 选择器匹配属于其父元素的第 N 个子元素&#xff0c;不论元素的类型。n 可以是数字、关键词或公式。先看下面一段代码&#xff1a;第一行第二行第三行第四行第五行如果我们想单独给某一行添加特殊的样式代码&#xff0c;在不使用nth-child的情况下&…

对没有标记为安全的activex控件进行初始化和脚本运行_RASP攻防 —— RASP安全应用与局限性浅析...

文&#xff5c;【腾讯安全平台部数据安全团队】 qiye & baz 前言随着Web应用攻击手段变得复杂&#xff0c;基于请求特征的防护手段&#xff0c;已经不能满足企业安全防护需求。在2012年的时候&#xff0c;Gartner引入了“Runtime application self-protection”一词&#x…

java中堆和栈有什么区别?

堆和栈都是Java用来在RAM中存放数据的地方。 一、堆 (1)Java的堆是一个运行时数据区&#xff0c;类的对象从堆中分配空间。这些对象通过new等指令建立&#xff0c;通过垃圾回收器来销毁。 (2)堆的优势是可以动态地分配内存空间&#xff0c;需要多少内存空间不必事先告诉编译…

cass坡度土方计算案例_【九天教您南方cass 9.1】 12 道路断面土方计算

同学们大家好&#xff0c;欢迎收看由老王测量上班记出品的cass9.1视频课程我是本节课主讲老师九天。我们讲课的教程附件也是共享的&#xff0c;请注意索取 在测量空间中。【点击索取cass教程】5元立得 (给客服说暗号&#xff1a;“老王测量上班记”) 即可5元获得教程全系列&…

台式机dp接口_精品导购:你想要的商务台式机 都在这里了!

不少公司都会为员工配备办公电脑&#xff0c;而公司在采购这些电脑时&#xff0c;兴许可能对电脑性能、存储容量等都没有研究过&#xff0c;只是图了价格便宜便批量采购&#xff0c;这就导致电脑在使用一段时间后&#xff0c;会频繁出现死机、运行卡顿和硬盘容量不够等情况的发…

roc曲线怎么绘制_ROC曲线和PR曲线

在机器学习中&#xff0c;ROC曲线被广泛应用于二分类问题中来评估分类器的可信度&#xff0c;当处理一些高度不均衡的数据集时&#xff0c;PR曲线能表现出更多的信息。在二分类问题中&#xff0c;分类器将一个实例的分类标记为正例还是负例&#xff0c;这可以用一个混淆矩阵来表…

火狐受信任站点设置_火狐浏览器怎么添加信任站点,谷歌浏览器设置信任站点...

我们总是喜欢在win7系统中使用浏览器来浏览一些网页&#xff0c;有时候需要添加信任网址&#xff0c;防止每次打开的时候都会跳出提示&#xff0c;而有的网页需要添加受限制&#xff0c;防止浏览网页弹出某些广告网站&#xff0c;可是最近有win7专业版系统用户却发现在添加信任…

这是2019年适合Java程序员读的10本书

除了为经验丰富的Java开发人员&#xff08;他们更倾向于学习架构方面的知识&#xff0c;关于云、微服务、Java 9和Spring 5开发等&#xff09;推荐了一些书籍&#xff0c;同时也为那些初级程序员或经验相对缺乏的Java开发者推荐一些适合在2019年学习的书&#xff0c;下面还是来…

华三交换机路由器图标_弱电箱网口不够用,用华三8口千兆交换机搞定

如题&#xff0c;公司租的办公室刚装修完&#xff0c;安了弱电箱&#xff0c;无奈联通只给了一个2口的光猫&#xff0c;如何不自己花钱买光猫的前提下&#xff0c;分配三间屋子的五个有线成了问题。之前考虑过直接路由器内置在弱电箱里&#xff0c;不过电箱金属盒有屏蔽和弱电箱…

i2c hid 触摸板不能用_零基础学硬件(6):I2C总线的用处

I2C总线的用处&#xff0c;什么时候需要用I2C总线这东西太简单了,我还有点不想说..不就是一个start一个STOP一个ACK嘛,,简单得不能在简单.他可以根据器件地址进行通信..当年在学校时看了很多这资料..什么时候需要用I2C总线&#xff0c;你的器件是IIC的器件,我就得用IIC总线..什…

problem a: 简单的整数排序_python里的排序

本篇文章主要讲&#xff1a;自定义规则排序 多字段排序开讲之前&#xff0c;先讲一些简单sorted()或者sort()&#xff0c;两者返回值不同&#xff01;例如&#xff1a;sorted([5, 2, 3, 1, 4]) # 输出&#xff1a;[1, 2, 3, 4, 5]另一个呢a [5, 2, 3, 1, 4] a.sort() a # 输出…

python prettytable表格列数太多_excel列数太多了怎么办

excel列数太多了怎么办&#xff1f;列数太多我们需要巧用组合键&#xff0c;通过组合键达到比隐藏更实用的效果。下面将用excel2007版本为例&#xff0c;效果图见下。方法&#xff1a;1、如果列太多&#xff0c;我们就细分为多少列分布做&#xff0c;具体多少列为一组&#xff…

c++ 多态 运行时多态和编译时多态_C++核心编程 第十一节 多态

前言&#xff1a;多态是C面向对象三大特性之一。多态&#xff0c;指的是一个类实例的相同方法在不同情形有不同表现形式。具有不同内部结构的对象可以共享外部接口。C多态就是用一个更通用的基类指针指向不同的子类实例&#xff0c;为了能调用正确的方法&#xff0c;我们需要用…

oracle sql 子游标_Oracle 父子游标

游标从Oracle数据库管理员的角度上说&#xff0c;游标是对存储在库缓存中的可执行对象的统称。SQL语句是存储在库缓存中的&#xff0c;它是游标。除了它之外&#xff0c;还有Oracle的存储过程也是存储在库缓存中的可执行对象&#xff0c;从Oracle DBA的角度上说&#xff0c;它也…

多线程操作时操作系统时间片_从零开始自制操作系统(15):内核多线程

1.多线程原理&#xff1a;&#xff08;1&#xff09;概述&#xff1a;多线程是指CPU可以在一段时间中并行执行多个程序&#xff0c;比如我们可以一边听音乐、一边写代码&#xff08;这两个程序可以“同时进行”&#xff0c;我们称之为多进程&#xff0c;而多进程实现的本质就是…

听说java又过气了?看我运用大数据分析2019年java发展趋势!

近些年的技术圈&#xff0c;单以计算机语言界来说&#xff0c;稳坐第一把太师椅的 Java “或将被取代”、迎接转折点、Java 项目工程师风光不再等言论不绝于耳。在焦虑的大环境下&#xff0c;所有人好像都看起来很焦虑不安。 针对这类“唱衰论”&#xff0c;也不难理解。不仅&…

打开git界面_使用 Gitea 快速搭建私有 Git 版本控制服务

1. 前言分布式版本控制工具 Git 已经是现代软件源代码版本控制首选方案之一。公有 Git 服务提供商 国外知名如 GitHub 国内网络延迟高,Gitlab 涉嫌对中国的歧视不推荐。国内有 Gitee、Coding 生态还不错。但是一般公司的源代码除非开源项目是不会放在公有 Git 服务上的。所以我…