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用作方法返回类型有三点看法。

  1. 单个return或多个return s对意外返回null而不是“空”或其他非null的可能性的影响在确定单个返回或多个返回是否最有意义时应考虑Optional引用。
  2. 通过在整个方法中处理基础类型并仅在最新时刻(通常在return )实例化返回的Optional ,通常更容易确保返回Optional引用而不是返回null
  3. 最终将要从方法返回的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的可选项时的注意事项相关推荐

  1. 写java代码时的注意事项_从方法返回Java 8的可选项时的注意事项

    写java代码时的注意事项 Java 8引入的Optional类一直是该语言版本引入的最具争议的功能之一. 尽管我喜欢这个新的Java类的东西比不喜欢的东西多,但在Java方法中将其用作return类 ...

  2. java中如何返回四维数组_如何从Java中的方法返回数组?

    我们可以从Java中的方法返回Java中的数组.在这里,我们有一个createArray()方法,通过从用户那里获取值来动态创建一个数组并返回创建的数组. 示例import java.util.Arr ...

  3. java泛型函数 返回值_java 泛型(类)方法返回值为什么是 Object??

    我认知中,java 虚拟机是不认识泛型类或泛型方法的,所以在编译成字节码的时候,所有的泛型类或泛型方法,都会被转换成普通的类或方法. 例如: // 泛型类 class Test { public T ...

  4. Java报异常时getMessage()方法返回null

    Java报异常时getMessage()方法返回null 参考文章: (1)Java报异常时getMessage()方法返回null (2)https://www.cnblogs.com/runnin ...

  5. 【Java 虚拟机原理】Class 字节码二进制文件分析 五 ( 方法计数器 | 方法表 | 访问标志 | 方法名称索引 | 方法返回值类型 | 方法属性数量 | 方法属性表 )

    文章目录 前言 一.方法表结构 二.方法计数器 三.方法表数据解析 ( init 构造方法 ) 1.方法访问标志 2.方法名称索引 3.方法返回类型 4.方法属性数量 前言 上一篇博客 [Java 虚 ...

  6. Java黑皮书课后题第7章:7.10(找出最小元素的下标)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素下标。编写测试程序,提示用户输入10个数字,调用这个方法返回最小值的下标(多个则最小

    7.10(找出最小元素的下标)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素下标.编写测试程序,提示用户输入10个数字,调用这个方法返回最小值的下标(多个则返回最小的下标) 题目 题目描述 ...

  7. Java黑皮书课后题第7章:7.9(找出最小元素)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素。编写测试程序,提示用户输入10个数字,调用这个方法返回最小值,并显示这个最小值

    7.9(找出最小元素)使用下面的方法头编写一个方法,求出一个整数数组中的最小元素.编写测试程序,提示用户输入10个数字,调用这个方法返回最小值,并显示这个最小值 题目 题目描述与运行示例 破题 代码 ...

  8. Java黑皮书课后题第6章:6.37(格式化整数)编写一个测试程序,提示用户输入一个数字以及宽度,显示通过调用format方法返回的字符串

    6.37(格式化整数)编写一个测试程序,提示用户输入一个数字以及宽度,显示通过调用format方法返回的字符串 题目 题目描述 破题 代码 运行示例 题目 题目描述 6.37(格式化整数) 使用下面的 ...

  9. java方法带参数返回值_Java方法中的参数太多,第6部分:方法返回

    java方法带参数返回值 在当前的系列文章中,我正在致力于减少调用Java方法和构造函数所需的参数数量,到目前为止,我一直专注于直接影响参数本身的方法( 自定义类型 , 参数对象 , 构建器模式 , ...

最新文章

  1. 月薪40~50K|波波生活信息技术公司招聘高级算法工程师
  2. python自学网课-python网课学习笔记--4
  3. 26.python常用端口号
  4. 辨异 —— 行星 vs 恒星
  5. jspx格式手机打开_制作手机浏览器显示格式的HTML页面
  6. 关于 SET QUOTED_IDENTIFIER ON 和 SET ANSI_NULLS ON
  7. c语言中尖括号的作用,C语言中,#include
  8. rvm install 1.9.2 p136版本ruby
  9. 解决UE4官方文档C++API查询慢问题
  10. 【RQNOJ86】智捅马蜂窝【最短路】
  11. Express 框架 以及特性
  12. mysql bin_mysql-bin是什么文件?
  13. word打开文档很久很慢_解决直接打开Word、Excel文档很慢,而通过先打开WORD、EXCEL程序再打开文档则很快的问题...
  14. 结构方程模型中的R方改变量怎么求?
  15. 您的首个 App 内购买项目必须以新的 App 版本提交
  16. C++中rand函数和srand函数
  17. 20个经典的Java应用
  18. Ring Buffers (环形消息缓冲区)
  19. js ... es6中三个点是什么意思 真名叫扩展运算符
  20. gpu-z怎么用,显卡怎么看体质

热门文章

  1. BZOJ 3513: [MUTC2013]idiots [FFT]
  2. P2604 ZJOI2010 网络扩容,费用流裸题
  3. 动态规划训练13 [Catch That Cow poj3278]
  4. 21、mysql修改密码的方法总结
  5. mybatis源码阅读(二):mybatis初始化上
  6. MySQL group_concat()函数
  7. hibernate多对多、正向工程创建数据表——访问温馨提示
  8. React中构造函数、reader和函数的调用次数和时机测试
  9. 第5步 配置pom.xml文件 pom文件好了就是jar包引入好了
  10. phpst安装memcache扩展_在 Ubuntu/Debian 下安装 PHP7.3 教程