本文地址: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. 【斐波那契DP】HDU 4639——HeHe

    题目:点击打开链接 多校练习赛4的简单题,但是比赛的时候想到了推导公式f(n)=f(n-1)+f(n-2)(就是斐波那契数列),最后却没做出来. 首先手写一下he(不是hehe)连续时的规律.0-1 ...

  2. linux makefile: c++ 编程_基础入门_如何开始?

    学习android 终究还是需要研究一下其底层框架,所以,学习c++很有必要. 这篇博客,算是linux(ubuntu) 下学习 c++ 的一个入门. 刚开始学习编程语言的时候,最好还是使用命令行操作 ...

  3. 【50】了解new和delete的合理替换时机

    1.有时候,我们替换掉编译器提供的new或者delete.首先思考,为什么想要替换?下面是三个常见理由: a.用来检测运用上的错误,超额分配一些内存,再额外的空间放置一些内存: b.为了强化效能,编译 ...

  4. uploadify上传文件Firefox浏览器上传失败解决方法

    近期做文件上传使用到了uploadify 可是出现了各种奇葩的问题.并且针对各个不同浏览器问题不同 在Firefox中.非常坑爹的是.每次上传就丢失session值,可是我的系统在登录.保存文件文件夹 ...

  5. paip.超实用 360浏览器最近频繁奔溃解决流程.

    paip.超实用 360浏览器最近频繁奔溃解决流程. 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.csdn.n ...

  6. 给定表达式[x/2] + y + x * y, 其中x,y都是正整数。

    改进了一下,不过还是要十多秒吧. package com.boco.study; import java.math.BigDecimal; import java.util.Calendar; imp ...

  7. 字符编码的故事(ASCII,ANSI,Unicode,Utf-8区别)转载

    http://www.imkevinyang.com/2009/02/字符编解码的故事(ascii,ansi,unicode,utf-8区别).html 很久很久以前,有一群人,他们决定用8个可以开合 ...

  8. Linux性能及调优指南(翻译)之Linux内存架构

    http://blog.csdn.net/ljianhui/article/details/46734115

  9. 慎用StringEscapeUtils.escapeHtml步骤

    慎用StringEscapeUtils.escapeHtml方法[转] 推荐使用Apache commons-lang的StringUtils来增强Java字符串处理功能,也一直在项目中大量使用Str ...

  10. Events

    Events The idea behind Events is the ability to send data, as parameters, to interested Listeners an ...