从方法返回Java 8的可选项时的注意事项
Java 8引入的Optional类一直是该语言版本引入的最具争议的功能之一。 尽管我喜欢这个新的Java类的东西比不喜欢的东西多,但在Java方法中将其用作return
类型时,需要考虑一些事情。 我将在本文中讨论其中的一些问题,但不会讨论有关是否应该将Optional
限制为用作返回类型的争论 。 我还假定Optional
仅在期望在某些情况下该方法不应该返回任何值时才用作返回类型。 最后,这些观察结果适用于其他类型,并且也直接在Java中使用null
,但是Optional
强调并具体说明了这些观察结果。
单一收益与多重收益
在一般的软件开发社区和Java开发社区中,有一段时间一直在争论(“ 宗教战争 ”)关于是否应该编写方法仅return
一次(在本次讨论中不计入抛出异常 )的争论。 一方面, Yegor Bugayenko认为“ 许多返回语句在OOP中不是一个好主意 ”, Tom Dalling认为“ 从函数中获得一个退出点(返回)是一件好事 ”,而且许多人认为经常有多个return
语句表示需要重构该方法 。 另一方面, 布鲁斯·埃克尔(Bruce Eckel)认为 ,多个return
语句可使代码更“清晰”, 泰勒·高铁 ( Taylor Gautier)认为,“ 格言(Maxim) ”“一种方法应该只有一个出口点”“不会再错了”, 彼得Ritchie认为, 严格遵守单出口,如今会导致“面向对象的语言”中的“可读性较低”的代码,而Mark Levison概述了“ 一些我不喜欢单出口论点的原因 。”
Nicolai Parlog在“ 多重返回语句 ”一文中 ,介绍了方法仅返回一次的想法的历史以及需要考虑的事项。 他包括“多重收益表的情况”一节,其中概述了“一种方法可以从多个收益表中获利的几种情况。” 我最好的猜测是,许多开发商觉得我做的方式,这是“这取决于”决定一个特定的方法是否应该只有一个的时候return
陈述或应该有一个以上的return
声明。
当我开始更频繁地将Java 8的Optional用于我的方法的返回类型时,我发现在确定是从方法中返回一次还是多次时,还需要考虑使用Optional作为返回类型。
在声明Java方法返回Optional
,重要的是要充分理解这并不妨碍编写此方法的开发人员返回null
。 返回的Optional
是引用类型,并且与任何引用类型一样,可以为null
。 至关重要的是,开发人员编写返回Optional
的方法时, 切勿让该方法返回null
[通常应返回Optional.empty()来代替]。 我将用两句话来重申这一点:
- 第三版 , 有效Java中项目#55中突出显示的句子:“ 切勿从
Optional
-returning方法返回空值。 “ - 斯图尔特·马克(Stuart Marks)使用
Optional
的#1规则 ,“永远,永远不要对Optional变量或返回值使用null。”
一个方法中针对多个return语句的参数之一是,它使得识别每种情况下返回的内容变得更加困难(查找所有可能的返回方案)。 使用Optional
作为返回类型的一个具体示例说明了这一点。 一个人要确保在某些情况下自己的方法不会返回null
,而在其他情况下则要确保返回Optional
实例。 编译器当然不会在每种情况下返回哪个值。
解决此问题的一种方法是只从方法中返回一次,然后开发人员编写代码,而开发人员查看代码则可以轻松地确保不返回null
。 这些开发人员将只需要查找Optional.of(T)调用, Optional.ofNullable(T)调用或Optional.empty()调用。
在方法中使用基础数据类型的局部变量
当在返回点实例化Optional
时,这种避免意外返回null
而不是空Optional
最有效。 换句话说,我发现最好在整个方法中使用Optional
包装的类型,然后在最后可能的时候将其放在Optional
中。 下一个代码清单提供了这些荒谬的琐碎示例。
声明最终以可选方式返回的局部变量的示例
/*** Provides the middle name if it exists.** @return Middle name if it exists or empty if it doesn't exist.*/
public Optional<String> determineMiddleName1()
{String middleName;// Do whatever logic is necessaryreturn Optional.ofNullable(middleName);
}/*** Provides the middle name if it exists.** @return Middle name if it exists or empty if it doesn't exist.*/
public Optional<String> determineMiddleName2()
{Optional<String> middleName;// Do whatever logic is necessaryreturn middleName;
}
在上面的代码中, determineMiddleName 1 ()
方法与基础类型的局部变量一起使用。 通常,这比Optional
更容易设置/填充,并且在末尾使用Optional.isNullable()
可确保即使是null
MiddleName也将作为“空”的Optional
而不是null
。
上面的代码中的defineMiddleName determineMiddleName 2 ()
方法声明其局部变量,该局部变量最终将作为Optional<String>
返回,然后在该方法末尾返回该引用。
避免局部变量的“默认”初始化
在上面编写方法defineMiddleName determineMiddleName 2 ()
,编译器将帮助确保将局部变量“ middleName”设置为某物(即使该“ something”为null
),但开发人员已选择将其“ middleName”变量初始化为null
开头,编译器将不会有任何问题。 如果由于某种原因需要初始化局部变量,最好将其初始化为Optional.empty()
而不是null
。 如果开发人员选择使用Optional.empty()
初始化该变量,那么第二个示例仍然有可能在该方法的后面将本地变量“重置”为null
。
该讨论使我对Java中将Optional
用作方法返回类型有三点看法。
- 单个
return
或多个return
s对意外返回null
而不是“空”或其他非null
的可能性的影响在确定单个返回或多个返回是否最有意义时应考虑Optional
引用。 - 通过在整个方法中处理基础类型并仅在最新时刻(通常在
return
)实例化返回的Optional
,通常更容易确保返回Optional
引用而不是返回null
。 - 最终将要从方法返回的
Optional
类型的局部变量,即使“已知”将适当地重新设置,也绝不应最初将其分配为null
。 最好根本不要定义它,以便编译器将确保需要在代码流的每个“分支”中对其进行设置。 最起码,如果是进行初始化,类型的那个局部变量Optional
应该被初始化为Optional.empty()
而不是向null
。
这些观察可以合并。 例如,当确定某个方法应具有多个返回(例如实现guard子句 )时,可以在每次返回时返回适当的非null
Optional
引用,并且直到需要时才初始化局部变量(通过警卫)。 下一个可笑的例子说明了这一点。
避免使用多个返回语句返回空值的示例
public Optional<String> getGuardedData(final String input)
{if (input == null){return Optional.empty();}String data;// Do whatever logic is necessaryreturn Optional.ofNullable(data);
}
我发现Optional
类在正确用作方法返回类型时,由于它的流利程度更高,可以使客户端的代码更具可读性。 但是,要获得其最大值,必须遵循纪律应用Optional
,以便代码的客户可以期望返回的Optional
永远不会为null
。 这篇文章研究了一些注意事项,可以帮助确保从不会将自已声明为return Optional
的方法返回null
。 没有信任,该方法不会返回null
,使用Optional
的返回类型只能使事情变得更糟,因为它迫使客户端的非第一次检查null
Optional
调用上的方法之一,之前Optional
。 这使得调用代码不太流畅 。
翻译自: https://www.javacodegeeks.com/2018/01/considerations-returning-java-8s-optional-method.html
从方法返回Java 8的可选项时的注意事项相关推荐
- 写java代码时的注意事项_从方法返回Java 8的可选项时的注意事项
写java代码时的注意事项 Java 8引入的Optional类一直是该语言版本引入的最具争议的功能之一. 尽管我喜欢这个新的Java类的东西比不喜欢的东西多,但在Java方法中将其用作return类 ...
- java中如何返回四维数组_如何从Java中的方法返回数组?
我们可以从Java中的方法返回Java中的数组.在这里,我们有一个createArray()方法,通过从用户那里获取值来动态创建一个数组并返回创建的数组. 示例import java.util.Arr ...
- java泛型函数 返回值_java 泛型(类)方法返回值为什么是 Object??
我认知中,java 虚拟机是不认识泛型类或泛型方法的,所以在编译成字节码的时候,所有的泛型类或泛型方法,都会被转换成普通的类或方法. 例如: // 泛型类 class Test { public T ...
- Java报异常时getMessage()方法返回null
Java报异常时getMessage()方法返回null 参考文章: (1)Java报异常时getMessage()方法返回null (2)https://www.cnblogs.com/runnin ...
- 【Java 虚拟机原理】Class 字节码二进制文件分析 五 ( 方法计数器 | 方法表 | 访问标志 | 方法名称索引 | 方法返回值类型 | 方法属性数量 | 方法属性表 )
文章目录 前言 一.方法表结构 二.方法计数器 三.方法表数据解析 ( init 构造方法 ) 1.方法访问标志 2.方法名称索引 3.方法返回类型 4.方法属性数量 前言 上一篇博客 [Java 虚 ...
- Java黑皮书课后题第7章:7.10(找出最小元素的下标)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素下标。编写测试程序,提示用户输入10个数字,调用这个方法返回最小值的下标(多个则最小
7.10(找出最小元素的下标)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素下标.编写测试程序,提示用户输入10个数字,调用这个方法返回最小值的下标(多个则返回最小的下标) 题目 题目描述 ...
- Java黑皮书课后题第7章:7.9(找出最小元素)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素。编写测试程序,提示用户输入10个数字,调用这个方法返回最小值,并显示这个最小值
7.9(找出最小元素)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素.编写测试程序,提示用户输入10个数字,调用这个方法返回最小值,并显示这个最小值 题目 题目描述与运行示例 破题 代码 ...
- Java黑皮书课后题第6章:6.37(格式化整数)编写一个测试程序,提示用户输入一个数字以及宽度,显示通过调用format方法返回的字符串
6.37(格式化整数)编写一个测试程序,提示用户输入一个数字以及宽度,显示通过调用format方法返回的字符串 题目 题目描述 破题 代码 运行示例 题目 题目描述 6.37(格式化整数) 使用下面的 ...
- java方法带参数返回值_Java方法中的参数太多,第6部分:方法返回
java方法带参数返回值 在当前的系列文章中,我正在致力于减少调用Java方法和构造函数所需的参数数量,到目前为止,我一直专注于直接影响参数本身的方法( 自定义类型 , 参数对象 , 构建器模式 , ...
最新文章
- 月薪40~50K|波波生活信息技术公司招聘高级算法工程师
- python自学网课-python网课学习笔记--4
- 26.python常用端口号
- 辨异 —— 行星 vs 恒星
- jspx格式手机打开_制作手机浏览器显示格式的HTML页面
- 关于 SET QUOTED_IDENTIFIER ON 和 SET ANSI_NULLS ON
- c语言中尖括号的作用,C语言中,#include
- rvm install 1.9.2 p136版本ruby
- 解决UE4官方文档C++API查询慢问题
- 【RQNOJ86】智捅马蜂窝【最短路】
- Express 框架 以及特性
- mysql bin_mysql-bin是什么文件?
- word打开文档很久很慢_解决直接打开Word、Excel文档很慢,而通过先打开WORD、EXCEL程序再打开文档则很快的问题...
- 结构方程模型中的R方改变量怎么求?
- 您的首个 App 内购买项目必须以新的 App 版本提交
- C++中rand函数和srand函数
- 20个经典的Java应用
- Ring Buffers (环形消息缓冲区)
- js ... es6中三个点是什么意思 真名叫扩展运算符
- gpu-z怎么用,显卡怎么看体质
热门文章
- BZOJ 3513: [MUTC2013]idiots [FFT]
- P2604 ZJOI2010 网络扩容,费用流裸题
- 动态规划训练13 [Catch That Cow poj3278]
- 21、mysql修改密码的方法总结
- mybatis源码阅读(二):mybatis初始化上
- MySQL group_concat()函数
- hibernate多对多、正向工程创建数据表——访问温馨提示
- React中构造函数、reader和函数的调用次数和时机测试
- 第5步 配置pom.xml文件 pom文件好了就是jar包引入好了
- phpst安装memcache扩展_在 Ubuntu/Debian 下安装 PHP7.3 教程