首页 > 编程语言 >读Java实战(第二版)笔记07_用Optional取代null

读Java实战(第二版)笔记07_用Optional取代null

时间:2023-02-12 07:11:05浏览次数:39  
标签:Java 07 4.3 变量值 5.16 5.14 null Optional

1. null的由来

1.1. 历史上被引入到程序设计语言中,目的是为了表示变量值的缺失

1.2. 包括Java在内的大多数现代程序设计语言为了与更老的语言保持兼容

2. null带来的问题

2.1. 错误之源

2.1.1. NullPointerException是最典型的异常

2.2. 代码膨胀

2.2.1. 深度嵌套的null检查

2.3. 自身毫无意义

2.3.1. 自身没有任何的语义

2.3.2. 以一种错误的方式对缺失变量值的建模

2.4. 破坏了Java的哲学

2.4.1. 让程序员意识到指针的存在

2.4.2. null指针

2.5. 在类型系统上开了个口子

2.5.1. null并不属于任何类型

2.5.2. null可被赋值给任意引用类型的变量

3. 防御式检查NullPointerException

3.1. 深层质疑

3.1.1. 每次你不确定一个变量是否为null时,都需要添加一个进一步嵌套的if块,这也增加了代码缩进的层数

3.2. 过多的退出语句

3.2.1. 为了避免深层递归的if语句块

3.2.2. 但这种流程是极易出错的

4. null的替代品

4.1. Groovy

4.1.1. 安全导航操作符(safe navigation operator,标记为?)

4.1.2. 可以安全访问可能为null的变量

4.1.3. 掩耳盗铃

4.2. Haskell

4.2.1. Maybe类型

4.2.1.1. 对Optional值的封装

4.2.1.2. 可以是指定类型的值

4.2.1.3. 可以什么都不是

4.3. Scala

4.3.1. Option[T]

4.3.1.1. 显式地调用Option类型的available操作,检查该变量是否有值

4.3.1.1.1. 变相的“null检查”
4.3.1.1.2. 类型系统默认会强制进行检查

4.3.1.2. 可以包含类型为T的变量

4.3.1.3. 可以不包含该变量

4.4. Java

5. java.util.Optional

5.1. 封装Optional值的类

5.1.1. 对存在或缺失的变量值进行建模

5.1.2. 用户只需要阅读方法签名,就能了解该方法是否接受一个Optional类型的值

5.1.3. 不再需要为其添加null的检查

5.1.3.1. 因为null的检查只会掩盖问题,并未真正地修复问题

5.2. 清晰界定变量值缺失原因

5.2.1. 结构上的问题

5.2.2. 算法上的缺陷

5.2.3. 数据中的问题

5.3. 设计初衷仅仅是要支持能返回Optional对象的语法

5.3.1. 没特别考虑将其作为类的字段使用

5.3.2. 并未实现Serializable接口

5.3.2.1. 替代方案提供一个能访问声明为Optional、变量值可能缺失的接口

5.4. Optional.empty

5.4.1. 声明一个空的Optional

5.4.2. 变量不存在时返回Optional类的特定单一实例

5.5. Optional.of

5.5.1. 依据一个非空值创建Optional

5.6. Optional.ofNullable

5.6.1. 可接受null的Optional

5.6.2. 创建一个允许null值的Optional对象

5.7. get()

5.7.1. 最简单但又最不安全的方法

5.7.2. 抛出一个NoSuchElementException异常

5.8. orElseThrow(Supplier<? extends="" x=""? > exceptionSupplier)

5.8.1. 类似get方法

5.8.2. 定制希望抛出的异常类型

5.9. orElse(T other)

5.9.1. Optional对象不包含值时提供一个默认值

5.10. orElseGet(Supplier<? extends="" t=""? > other)

5.10.1. orElse方法的延迟调用版

5.10.2. Supplier方法只有在Optional对象不含值时才执行调用

5.10.3. 应用场景

5.10.3.1. 创建默认值是件耗时费力的工作,借此提升程序的性能

5.10.3.2. 非常确定某个方法仅在Optional为空时才进行调用

5.11. or(Supplier<? extends=""? ><? extends="" t=""? >> supplier)

5.11.1. Java9

5.11.2. 类似orElseGet方法

5.11.3. 不会解包Optional对象中的值,即便该值是存在的

5.12. ifPresent(Consumer<? super="" t=""? >consumer)

5.12.1. 变量值存在时,执行一个以参数形式传入的方法

5.12.2. 变量值不存在时,就不进行任何操作

5.13. ifPresentOrElse(Consumer<? super="" t=""? > action, Runnable emptyAction)

5.13.1. Java9

5.13.2. 接受一个Runnable方法,如果Optional对象为空,就执行该方法所定义的动作

5.14. 和Stream接口的相似之处

5.14.1. map方法

5.14.1.1. 使用map从Optional对象中提取和转换值

5.14.2. flatMap方法

5.14.2.1. 使用flatMap链接Optional对象

5.14.3. filter方法

5.14.3.1. 使用filter剔除特定的值

5.15. 操纵由Optional对象构成的Stream

5.15.1. Java9

5.15.2. 把一个含值的Optional对象转换成由该值构成的Stream对象

5.15.3. 把一个空的Optional对象转换成等价的空Stream

5.16. 基础类型的Optional对象

5.16.1. OptionalInt

5.16.2. OptionalLong

5.16.3. OptionalDouble

5.16.4. 不推荐

5.16.4.1. Optional对象最多只包含一个值

5.16.4.2. 基础类型的Optional不支持map、flatMap以及filter方法

标签:Java,07,4.3,变量值,5.16,5.14,null,Optional
From: https://www.cnblogs.com/lying7/p/17108974.html

相关文章

  • 类名和数据库的表名这样子相像的话,java类是不用弄数据表别名的
       ......
  • java基础
    1、初始化数据块   当创建对象或加载类时运行的代码。有两种类型:静态初始化器:加载类时运行的代码,static{ }括号之间的代码被称为静态初始化器。它只在第一次加载类时......
  • linux007之文件、目录操作命令
    查看当前所在目录:pwd:查看当前所在目录路径ls:查看当前目录所有文件ls路径:查看指定目录下所有文件ls-l:以列的形式查看当前目录所有文件ls-l路......
  • 蜗牛式学习Java--基础篇(2)--综合案例拼图游戏
      创建窗体代码:packagecom.ktestdemo;importjavax.swing.*;//继承JFramepublicclassPictureFrameextendsJFrame{//定义构造方法public......
  • Java线程中断
    Java线程里:“中断”就是指“终止”,与操作系统里的"中断"、“异常”是完全不同的概念;由于stop()方法过于暴力,可能导致资源回收无法风险、开销过大等问题,此方法已过期,故Java......
  • 8个 CSS & JavaScript 实现的照片库(相册)特效
    照片库(相册)是很多网站的必备功能,因为独特地呈现图像的能力可以帮助网站脱颖而出。网页开发者设计师正在利用这一优势,他们使用最新的CSS和JavaScript技术来创建抽象布局......
  • Java流程控制
    Java流程控制用户交互scanner//使用next,只输出接收到的第一个字符串(next中间不能加空格)//从键盘接收数据Scannerscanner=newScanner(System.in);System.out.p......
  • 7.6 提供相同运行环境的Java虚拟机
    一、不通过移植,也能利用虚拟机软件来运行其他操作系统的应用。通过利用该虚拟机,我们就可以在Macintosh的Mac操作系统上运行Windows应用了。VirtualPCforMAC可以使Maci......
  • 序列化与反序列化——作为Java开发,应该避开这些坑
     文章目录1.序列化与反序列化的概念2.子类实现Serializable接口,父类没有实现,子类可以序列化吗?3.类中存在引用对象,这个类对象在什么情况下可以实现序列化?4.同一个......
  • Java递归算法实例
    publicstaticvoidmain(String[]args){Map<String,Object>map=newHashMap<>();map.put("id",0);map.put("name","a");map.......