过多的使用null可能会导致大量的bugs,Google code 底层代码中,95%的集合类默认不接受null值。对null值,使用快速失败拒绝null比默认接受更好。

另外,null本身的含义很模糊。例如,对于null返回值,如Map.get(key)返回null,可能因为和key对应的值为null,也可能map中根本没有该key。null也可以用以表示失败或成功,可能代表任何事物。使用其他值而不是null可以使代码含义表达的更清楚。

尽管如此,有些地方还是应该使用null。在内存和速度方面,null是廉价的,并且在对象数组中是不可避免的。

基于以上原因,Guava大部分工具对null都设计为快速失败。另外,Guava提供了一些方便使用null的工具。

实际案例

不要在Set中使用null,也不要将null作为Map的key值,使用特殊值代替null可以让查找的语义更清晰。

如果你想把null作为Map的value,更好的办法不是将该条目放入Map中,而是应该以一个单独的Set维护“值为null”的键集合。因为Map中某个键对应的值为null和Map中没有某个键值很容易混淆。

如果需要在List中使用null,并且这个List是稀疏的,则使用Map<Integer, E>可能更好。

如果确实需要null,但null值不能和Guava的集合一起工作,则只能选择其他方式,如JDK中的Collections.unmodifiableList代替Guava中的ImmutableList。

Optional

Guava设计Optional来解决null问题,Optional<T>表示可能为null的T类型的引用。Optional实例要么包含一个非null的引用,要么什么都不包含(absent),从不会包含null值引用。在需要使用null的时候,可以用Optional代替。

Optional除了赋予null意义外,增加可读性,还在于它是一种傻瓜式的防护。Optional 迫使你积极思考引用确实的情况,因为你必须显式地从Optional 获取引用。

Optional 的可能应用方面:

  • 作为方法返回值,用于取代使用null作为返回值的情况。
  • 用于区分“unknow”(如Map不包含)和“known to have no value”(如Map包含该键,值为Optional.absent())。
  • 用于包装null引用,从而在不支持null的集合中使用。

创建Optional(均为静态方法)

Optional.of(T) 创建指定引用的Optional实例,对null值抛出NullPointException。建议直接传递常量参数。
Optional.absent() 创建引用缺失的Optional实例
Optional.fromNullable(T) 创建指定引用的Optional实例,若引用为null则表示缺失
assertEquals("training", Optional.of("training").get());

Optional<String> optionalName = Optional.absent();
assertFalse(optionalName.isPresent()); // Non-null instance
Optional<String> optionalName = Optional.fromNullable("bob");
assertEquals("bob", optionalName.get());
// null instance
assertSame(Optional.absent(), Optional.fromNullable(null));

查询方法(均为非静态方法)

boolean isPresent() 如果该Optional 包含非null引用,返回true。
T get() 返回Optional 所包含的引用,若引用缺失,则抛出IllegalStateException。
T or(T) 返回Optional 所包含的引用,若引用缺失,返回默认值。
T orNull() 返回Optional 所包含的引用,若引用缺失,返回null。
Set<T> asSet() 返回Optional所包含的singleton不可变集合,若为空,返回空集合。
public void testIsPresent_no() {
assertFalse(Optional.absent().isPresent());
} public void testIsPresent_yes() {
assertTrue(Optional.of("training").isPresent());
} public void testGet_absent() {
Optional<String> optional = Optional.absent();
try {
optional.get();
fail();
} catch (IllegalStateException expected) {
}
} public void testGet_present() {
assertEquals("training", Optional.of("training").get());
} public void testOr_T_present() {
assertEquals("a", Optional.of("a").or("default"));
} public void testOr_T_absent() {
assertEquals("default", Optional.absent().or("default"));
} public void testOrNull_present() {
assertEquals("a", Optional.of("a").orNull());
} public void testOrNull_absent() {
assertNull(Optional.absent().orNull());
} public void testAsSet_present() {
Set<String> expected = Collections.singleton("a");
assertEquals(expected, Optional.of("a").asSet());
} public void testAsSet_absent() {
assertTrue("Returned set should be empty", Optional.absent().asSet().isEmpty());
} public void testAsSet_presentIsImmutable() {
Set<String> presentAsSet = Optional.of("a").asSet();
try {
presentAsSet.add("b");
fail();
} catch (UnsupportedOperationException expected) {
}
} public void testAsSet_absentIsImmutable() {
Set<Object> absentAsSet = Optional.absent().asSet();
try {
absentAsSet.add("foo");
fail();
} catch (UnsupportedOperationException expected) {
}
}
												

guava – Optional的更多相关文章

  1. Java8 Optional && Guava Optional

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

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

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

  3. 还在重复写空指针检查代码?考虑使用 Optional 吧!

    一.前言 如果要给 Java 所有异常弄个榜单,我会选择将 NullPointerException 放在榜首.这个异常潜伏在代码中,就像个遥控炸弹,不知道什么时候这个按钮会被突然按下(传入 null ...

  4. 【Java 8】Optional 使用

    一.前言 如果要给 Java 所有异常弄个榜单,我会选择将 NullPointerException 放在榜首.这个异常潜伏在代码中,就像个遥控炸弹,不知道什么时候这个按钮会被突然按下(传入 null ...

  5. Guava-Optional可空类型

    接上篇Guava之Joiner和Splitter,本篇将介绍Guava的另外一个有用的对象Optional,这在Java中Google Guava首先给我们提出可空对象模型的.在其他语言如c#这是已经 ...

  6. 摘抄JPA官方文档原文 防呆

    Spring Data JPA - Reference Documentation Oliver GierkeThomas DarimontChristoph StroblMark PaluchVer ...

  7. Spring Data Commons 官方文档学习

    Spring Data Commons 官方文档学习   -by LarryZeal Version 1.12.6.Release, 2017-07-27 为知笔记版本在这里,带格式. Table o ...

  8. Guava学习笔记(1):Optional优雅的使用null

    转自:http://www.cnblogs.com/peida/archive/2013/06/14/Guava_Optional.html 参考:[Google Guava] 1.1-使用和避免nu ...

  9. Guava API学习之Optional 判断对象是否为null

    java.lang.NullPointerException,只要敢自称Java程序员,那对这个异常就再熟悉不过了.为了防止抛出这个异常,我们经常会写出这样的代码: Person person = p ...

随机推荐

  1. jquery中的$的特殊用法

    通过父级元素选取子元素, $('父元素选择器,子元素选择器')        $('子元素选择器',父元素jquery对象); 通过$创建代码片段 $('<div/>',{ 'class' ...

  2. java压缩和解压字符串,Byte数组,String

    在网上找到的压缩解压的工具类,可以压缩String字符串 /*** * 压缩GZip * * @param data * @return */ public static byte[] gZip(by ...

  3. python property详解

    Python中有一个被称为属性函数(property)的小概念,它可以做一些有用的事情.在这篇文章中,我们将看到如何能做以下几点: 将类方法转换为只读属性 重新实现一个属性的setter和getter ...

  4. (转) Deep Learning Resources

    转自:http://www.jeremydjacksonphd.com/category/deep-learning/ Deep Learning Resources Posted on May 13 ...

  5. C#与C/C++的交互

    引擎内核用C++为了保证运行速度,程序员可以使用C#来编写其他的业务逻辑,可以使用.NET类库中的绝大多数类,这样来降低开发难度,同时也降低了入门难度,可以吸引更多的.NET程序.

  6. Thread基本介绍

    1.Thread类介绍 Class Thread java.lang.Object java.lang.Thread All Implemented Interfaces: Runnable Dire ...

  7. save_data

    <?php /** * * $model 实例化表模型 * * $url 跳转地址 */ public function save_data($model,$url){ if(false === ...

  8. C#对象克隆介绍

    浅拷贝和深拷贝 有两种对象克隆的方法:浅拷贝和深拷贝.浅拷贝只是复制引用,而不会复制引用的对象.深拷贝会复制引用的对象. 因此,原始对象中的引用和浅拷贝对象中的同一个引用都指向同一个对象.而深拷贝的对 ...

  9. OData 带更新的实例,并能取得元数据格式类型

    http://www.cnblogs.com/kid1412/p/6012938.html#CreateANewEntity <<ABP框架>> OData 集成   文档目录 ...

  10. UISegmentedControl和UIStepper的使用

    UISegmentedControl:分栏控件,常用的属性和方法是 1.tintColor:控制分栏控件的颜色风格 2.insertSegmentWithTitle(Image):插入分栏标题(图片) ...