本文地址:http://www.cnblogs.com/hamhog/p/3536647.html

"null很恶心。" -Doug Lea

"这是一个令我追悔莫及的错误。" - Sir C. A. R. Hoare, 在评价他对null的发明时说。

使用和避免使用null

粗心地使用null能导致各种各样的bug。通过研究Google code base,我们发现大约95%的collection中不该含有null值。对于开发者来说,collection对null值如果能直接报错,会比默默接受更有帮助。

此外,null让人讨厌的一点在于它的含义模糊。函数返回值为null时,很少能让人明白是什么意思——比如,Map.get(key)返回null,可能是因为map中的值为null,也可能是因为map中没有对应的值。Null可以表示失败,可以表示成功,可以表示任何事情。想要表意清晰,就不要用null。

虽然这么说,也有时候用null是正确的选择。null在时间和空间上的代价都很低,并且在object array中不可避免。但是相对于官方库,在实际应用的代码中,null仍然是导致迷惑不清、奇怪bug和表义模糊的主要原因之一。还是上面的例子,当Map.get返回null,可能说明不存在对应的值,也可能说明值存在且为null。最大的问题在于,null无法提示这个null值表示什么意思。

因此,很多Guava utility设计为对null值直接报错;只要有不用null的代替方案,就不允许null值。另外,Guava提供了一些工具来帮你避免使用null,同时在你不得不用时让使用null更容易。

具体情况

如果你想把null加进Set中,或者作为Map的key——那就不要这么做。如果你根据情况显式地替换掉null,查找结果的含义会更加清晰。

如果你想把null用作Map的value——那就不要添加对应的entry,而要把key存进用另外一个专门的Set里。到底是Map中对应这个key的value为null,还是Map没有这个key的entry,这两种情况非常容易弄混。把值为null和不为null的这两种key分开存就要好得多了,在跟value相关联的key是null的情况下更是如此。

如果你想把null加进 List 里——如果list比较稀疏,也许用 Map<Integer, E> 更合适?这样可能效率更高,可能实际上更符合程序的需求。

设想一下如果有一个现成的"null object"可供使用。一般是没有的,但也有例外。比如,向一个 enum 加入常量,就代表了null的含义。再比如,java.math.RoundingMode 有个 UNNECESSARY 值来表示“不要取整,如果需要取整就抛出异常”。

如果你真的需要null值,使用不支持null的collection实现有困难,那只能换用另一种collection实现。例如,用 Collections.unmodifiableList(Lists.newArrayList()) 替换 ImmutableList 。

Optional类

很多情况下程序员会用 null 值来代表某种缺失:也许这里本来应该有个值,但现在没有,或是找不到。例如,Map.get 返回 null 值表示找不到这个key对应的value。

Optional<T> 是一种用非null值来替换可null的 T 引用的解决方案。一个 Optional 类要么包含一个非null的 T 引用(这种情况称为引用“存在(present)”),要么什么也不包含(这种情况称为引用“缺失(absent)”)。Optional 类从来不会“包含null”。

Optional<Integer> possible = Optional.of(5);
possible.isPresent();// returns true
possible.get();// returns 5

Optional 类并非与其他语言中的"option"或"maybe"结构完全等同,尽管可能有些相似性。

我们在此列出了一些常见的 Optional 类操作。

创建Optional

以下均为 Optional 类的静态方法:

Optional.of(T) 创建一个Optional实例,包含非null的给定引用T,如果T为null则直接报错。
Optional.absent() 返回一个absent的Optional实例。
Optional.fromNullable(T) 将有可能为null的引用T转换为Optional实例。如果T不为null则实例为present,T为null则实例为absent。

查询方法

以下均为具体 Optional<T> 实例上的非静态方法:

boolean isPresent() 如果包含非null的T(为present)实例,则返回 true 。
T get() 如果为present,返回包含的 T 实例;否则抛出 IllegalStateException 。
T or(T) 如果为present,返回包含的 T 实例;否则返回指定的默认值。
T orNull() 如果为present,返回包含的 T 实例;否则返回 null 。这个方法是 fromNullable 的逆过程。
Set<T> asSet() 如果为present,返回不可变的单例(singleton) Set ,Set中包含 Optional 中包含的 T 实例;否则返回一个空的不可变set。

除此之外,Optional 类还提供一些更方便的工具方法;查询Javadoc了解细节。

有何意义?

使用 Optional 除了能给 null 起个名字而增强可读性,最大的好处是它的防呆性。它会强迫你主动考虑值缺失的情况,否则就不能通过编译,因为你将需要主动解包 Optional 类,针对情况处理。讨厌的null太容易让人忘记该处理的事情,尽管FindBugs对此有些帮助,我们认为它还不足以解决问题。

Optional 这个优点的一个典型体现,就在于函数返回值既有可能"存在"也有可能"缺失"时。你(及其他人)在调用一个方法other.method(a,b)时忘记返回值可能为null的可能性,比你编写这个方法时会忘记参数 a 有为null的可能性大得多。返回值类型为 Optional 就杜绝了调用者忘记处理返回值为null的可能,因为调用者需要把返回值从 Optional 中解包出来,才能编译通过。

便捷方法

只要你想把一个 null 值替换为某个默认值,就可以用Objects.firstNonNull(T, T)。这个方法的功能顾名思义,如果两个参数 T 都是null,则直接报错,抛出NullPointerException。如果你在用 Optional,还有更好的方法——例如 first.or(second)。

Strings 中有一组方法用来处理可能为null的 String 值。这些命名直白的方法具体如下:

emptyToNull(String)
isNullOrEmpty(String)
nullToEmpty(String)

我们想要强调,这些方法最主要用来应对某些讨厌的API,它们把null String和空String("")等同处理。而每当你自己写出把null string和 "" 混合处理的代码,Guava团队都会哭泣。(如果这两者的含义显著不同,那还好一些。但是把它们当做完全一样的东西处理,是一种不幸很常见的代码坏味道。)

中文翻译自Guava官方文档:GuavaExplained - UsingAndAvoidingNullExplained   译者:戴仓薯

[Guava官方文档翻译] 2.使用和避免使用null (Using And Avoiding Null Explained)的更多相关文章

  1. [Guava官方文档翻译] 7. Guava的Immutable Collection(不可变集合)工具 (Immutable Collections Explained)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3538666.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...

  2. [Guava官方文档翻译] 6. 用Guava辅助Throwable异常处理 (Throwables Explained)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3537508.html ,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体 ...

  3. [Guava官方文档翻译] 5. Guava的Object公共方法 (Common Object Utilities Explained)

    我的技术博客经常被流氓网站恶意爬取转载.请移步原文:http://www.cnblogs.com/hamhog/p/3537367.html,享受整齐的排版.有效的链接.正确的代码缩进.更好的阅读体验 ...

  4. [Guava官方文档翻译] 4. 使用Guava Ordering排序 (Ordering Explained)

    本文地址:http://www.cnblogs.com/hamhog/p/3537233.html 示例 assertTrue(byLengthOrdering.reverse().isOrdered ...

  5. [Guava官方文档翻译] 3. 前置条件检查(Preconditions Explained)

    本文地址:http://www.cnblogs.com/hamhog/p/3536964.html 前置条件检查 Guava提供了一些检查前置条件的utilities.我们强烈建议静态import这些 ...

  6. [Guava官方文档翻译] 1.Guava简介 (Introduction)

    用户指南 Guava包含Google在Java项目中用到的一些核心库:collections, caching, primitives support, concurrency 库, common a ...

  7. Spring官方文档翻译(1~6章)

    Spring官方文档翻译(1~6章) 转载至 http://blog.csdn.net/tangtong1/article/details/51326887 Spring官方文档.参考中文文档 一.S ...

  8. Flume官方文档翻译——Flume 1.7.0 User Guide (unreleased version)中一些知识点

    Flume官方文档翻译--Flume 1.7.0 User Guide (unreleased version)(一) Flume官方文档翻译--Flume 1.7.0 User Guide (unr ...

  9. Flume官方文档翻译——Flume 1.7.0 User Guide (unreleased version)(二)

    Flume官方文档翻译--Flume 1.7.0 User Guide (unreleased version)(一) Logging raw data(记录原始数据) Logging the raw ...

随机推荐

  1. CentOS6.5安装MySQL及完全卸载

    原文地址:http://www.cnblogs.com/zhongshengzhen/ 第1步.yum安装mysql [root@localhost ~]# yum -y install mysql- ...

  2. 用RelativeLayout布局可以在imageview中写上文字

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  3. 将Excel数据导入MySql

    1.将选中的数据快儿拷贝到一个TXT文本文件中(记得把后面的空格消掉..),假如存到“D:\data.txt”这个位置里. 2.根据要导入的数据快儿建立MySql数据库和表,然后进入命令提示符里使用命 ...

  4. UIView的Touch事件UIControlEvents详解

    首先,UIControlEvents有这个几种: UIControlEventTouchDown = << , // on all touch downs UIControlEventTo ...

  5. PSObject

    PSBASE the raw view of the object PSADAPTED the fully adapted view of the object PSEXTENDED just the ...

  6. Design Pattern Explained 读书笔记二——设计模式序言

    设计模式的由来: 20 世纪 90 年代初,一些聪明的开发者偶然接触到 Alexander(Christopher Alexander 的建筑师) 有关模式的工作.他们非常想知道,在建筑学成立的理论, ...

  7. JS获取客户端电脑信息(转)

    <html> <head> <title></title> <script type="text/javascript"> ...

  8. html中#include file的使用方法

    有两个文件a.htm和b.htm,在同一文件夹下a.htm内容例如以下 <!-- #include file="b.htm" --> b.htm内容例如以下 今天:雨 ...

  9. IntelliTrace 调试、定位异常

    最近看了一个开源数据库管理,然后没有认真看它的配置环境,想看看是什么东西, 然后发现有类型转换的错误,但是一下子也定位不到哪里出错? 所以对于这种一下子找不到异常在哪里的,可以使用intellitra ...

  10. Making the impossible: 3 nodes intercontinental replication--转载

    原文:http://www.percona.com/blog/2012/01/11/making-the-impossible-3-nodes-intercontinental-replication ...