接上篇Guava之Joiner和Splitter,本篇将介绍Guava的另外一个有用的对象Optional,这在Java中Google Guava首先给我们提出可空对象模型的。在其他语言如c#这是已经存在很久的模式,并包含在.net类库中Nullable(Int?也是一个可空类型)。

Null sucks

回到本文主题Optional。在我日常编程中NullPointerException是肯定是大家遇见最多的异常错误:

为此Doug Lea曾说过:

Null sucks.

Sir C. A. R. Hoare也曾说过:

I call it my billion-dollar mistake.

从上面我们能够足以看出NullPointerExceptiond的出现频率和可恨之处。因此在GOF的设计模式中我们也专门提出了空对象模式(或称特例模式)来应对这可恶的NullPointerExceptiond。空对象模式主要以返回一些无意义并不影响处理逻辑的特定对象来替代null对象,从而避免没必要的null对象的判断。 例如在计算一组员工的总共薪资的时候,对于返回的null对象则我们可以返回默认值为了0薪资的员工对象,那么我们就不需要做任何null的判断。

员工薪资问题

那么在Guava的Optional又该怎么解决呢?在讲解Optional之前,让我们仍然以计算一组员工的总共薪资为例用原生java代码将来看看:

 
@Test
public void should_get_total_age_for_all_employees() throws Exception {
final List<Employee> list = Lists.newArrayList(new Employee("em1", 30), new Employee("em2", 40), null, new Employee("em4", 18));
int sum = 0;
for (Employee employee : list) {
if (employee != null) {
sum += employee.getAge();
}
}
System.out.println(sum);
}
private class Employee {
private final String name;
private final int age;
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}

如果换成Guava Optional将如何:

 
 @Test
public void should_get_total_age_for_all_employees() throws Exception {
final List<Employee> list = Lists.newArrayList(new Employee("em1", 30),
new Employee("em2", 40),
null,
new Employee("em4", 18));
int sum = 0;
for (Employee employee : list) {
sum += Optional.fromNullable(employee).or(new Employee("dummy", 0)).getAge();
}
System.out.println(sum);
}

从上面可以清晰看出,我们不在担心对象对空了,利用Optional的fromNullable创建了一个可空对象,并将其or上一个dummy的员工信息,所以在这里我们不在担心NullPointerExceptiond。

也许你会说和利用三目运算 ( _?:_)没什么差别,在此例子中功能是的确是没多大差距,但是个人觉得Guava更有语义,更通用一些,而且满足很多空对象模式使用的场景。

Optional API

*. OptionalObject.isPresent(): 返回对象是否有值。

*. Optional.absent(): 返回一个空Optional对象,isPresent() 将会返回false

*. Optional.of(): 创Optional对象,输入参数不能为null

*. Optional.fromNullable(): 创Optional对象,输入可以为null

*. OptionalObject.asSet(): 和Optional对象值合并,如果为null则返回size为0的Set

*. OptionalObject.or(): 和Optional对象值合并,如果为null为空加则返回or参数作为默认值

*. OptionalObject.orNull(): 和Optional对象值合并,如果为null为空加则返回Null作为默认值

上面的api都是我们在使用Optional的时候最常用的方法属性方法,注意如果我们创建了Optional对象,但是没有判断isPresent()是否存在,就直接get这是会抛异常的,这属于乱用Optional情况,和直接用Null并没什么差别。

 
final Optional<Object> obj = Optional.fromNullable(null);
final Object o = obj.get();

同样Optional为空对象模式,可以添加默认值,null不会影响我们的处理,如果为null我们无法继续程序处理的情况,需要抛异常或者中断的的,还是需要抛异常、中断,利用Preconditions.checkNotNull等,而不是继续套一层Optional对象,这也属于乱用Optional之列。

Guava-Optional可空类型的更多相关文章

  1. guava学习--Optional可空类型

    转载:http://www.cnblogs.com/whitewolf/p/4231783.html Null sucks 回到本文主题Optional.在我日常编程中NullPointerExcep ...

  2. Java8 Optional && Guava Optional

    Java8 -- Optional boolean isPresent():与obj != null()一样:调用get()前要调用isPresent()检查,不然会报错 Optional的三种构造方 ...

  3. 四、可空类型Nullable<T>到底是什么鬼

    值类型为什么不可以为空 首先我们都知道引用类型默认值都是null,而值类型的默认值都有非null. 为什么引用类型可以为空?因为引用类型变量都是保存一个对象的地址引用(就像一个url对应一个页面),而 ...

  4. C#可空类型

    C#创建可空类型对于有些可选类型的时候特别好用.创建可空类型用法直接上图. 执行效果 用法 运行效果

  5. 【C#】可空类型(Nullable)

    C# 可空类型(Nullable) C# 提供了一个特殊的数据类型,nullable 类型(可空类型),可空类型可以表示其基础值类型正常范围内的值,再加上一个 null 值. 例如,Nullable& ...

  6. C#可空类型的速度和GC Alloc测试

    在Unity中进行速度和GC Alloc的测试 测试脚本: using UnityEngine; using System; using System.Collections; using Syste ...

  7. swift_枚举 | 可为空类型 | 枚举关联值 | 枚举递归 | 树的概念

    ***************可为空的类型 var demo2 :we_demo = nil 上面这个代码串的语法是错的 为什么呢, 在Swift中,所有的类型定义出来的属性的默认值都不可以是nil ...

  8. [C#] 可空类型的实现原理

    int? 是可为null的值类型.只比int多一个值就是null. 思考: 同样的内存空间,怎么实现的多一个值的?都是4字节,32位,int?靠什么存在一个null值的. 发现: 分析一下内存,看看如 ...

  9. 07.C#泛型的限制和可空类型的简单说明(三章3.5-四章4.1)

    自己在写文章的同时,也是在学习,对于书中的语句很多其实没有太好的理解,读一本书,要消化!!!三章都是讲泛型的,最后写一下泛型的限制,对于本章学习的完结,one end,one begin. 看下面的代 ...

随机推荐

  1. Asp.net操作cookie大全

    实例代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 3 ...

  2. Google Chrome 调试

    [原文地址:http://www.cnblogs.com/QLeelulu/archive/2011/08/28/2156402.html ] 在Google Chrome浏览器出来之前,我一直使用F ...

  3. 前端js 判断输入的必须是数字,判断金钱

    //输入的必须是数字 $(".xzjl").on("keyup", ".num", function () { var v = $(this ...

  4. GDB常用命令

    一. gdb使用流程 1.编译生成可执行文件 gcc -g hello.c -o hello 2.启动gdb gdb hello 3. 在main处设置断点 break main 4.运行程序 run ...

  5. command not found,系统很多命令都用不了 ,修改环境变量

    bash: ***: command not found,系统很多命令都用不了,均提示没有此命令. 突然之间linux很多命令都用不了,均提示没有此命令. 这应该是系统环境变量出现了问题导致的. 解决 ...

  6. 安卓稳定性压测工具_monkey环境搭建(简易)

    1.准备工具: sdk(64位操作系统):http://pan.baidu.com/s/1kV33pll sdk(32位操作系统):http://pan.baidu.com/s/1gfnww87 2. ...

  7. 我与solr(三)--solr后台相关介绍

    1.DashBoard: 介绍了当前solr的相关信息,运行时间,版本信息,java虚拟机的配置信息. 注意我们的solr与lucence的版本号是保持一致的,而不同的lucence版本也需要对应的j ...

  8. STM32正交编码器驱动电机

    1.编码器原理        什么是正交?如果两个信号相位相差90度,则这两个信号称为正交.由于两个信号相差90度,因此可以根据两个信号哪个先哪个后来判断方向. 这里使用了TI12模式,例如当T1上升 ...

  9. JAVA里的异常

    一.概念和分类 JAVA程序设计语言中,异常对象都是Throwable类的一个实例.Throwable分为Error和Exception. 其中,Error类层次结构描述了JAVA运行时系统的内部错误 ...

  10. player.swf播放flv方式

    <embed src="../images/player.swf" allowFullScreen="true" quality="high&q ...