译文:我们为什么爱你--null(2.方案“零”)

96
凝枫
2014.09.09 14:21* 字数 1526

【译者序】
前一篇文章中原文作者漫谈了null的来源与引发的常见问题,本文将开始对3中如今流行的null处理方式进行讨论,首先讨论第一种方案

使用0来代替null

假设我们正在做一个在线购物的应用,用户可以在线下单购买商品。店家可以发布新商品,当然当这个新商品的价格还未定的时候,可以不填价格,先发布商品。

对于这个业务场景,下面哪种方案更好:

-- 不允许用户让价格为null,这样可以完全阻止空指针错误的发生。如果这个价格当下确实未定,那就填0好了;

-- 如果价格当下还未知,那就存null好了,给null敞开大门一次吧。

如果你去看看Stackoverflow上的这个问答——“用null还是用空集合”,你会发现这个问题的答案惊人的一致。

很多程序猿不知道怎么来区别处理“空”与“零”的关系,在我看来,若处理不当,这里面还会暗藏着严重的危机。比如,我一年多前想买个房子。我去一个房地产的网站,然后发现上面有很多房子的价格写着“0”。可把我乐坏了:“没逗我吧?免费送房子??”但我当然明白现实是残酷的——他们只是没写价格而已。在这个例子里,你可能会毫不犹豫的说:“这还用问吗?肯定是没写价格啊,谁没事吃饱了撑着给你送房子啊。”

但是这网站上其他很多房子却有写了售价,而且还有总体平均价格这些数据。我不知道这些均价计算里有没有包括“0”,这样一来搞不好会产生很多错误。换句话说,100,000、120,000 和 “未知”,这三个的均价是多少?技术上来说当然应该是回答“未知”了。但你觉得这是用户想看到的数据吗?我们当然希望看到的是明确的价格数字,像110,000这样,但弄不好到头来整出个73,333(这个数据我不知道原作者怎么突然冒出来的--译者),那显然是瞎扯淡了。而且,这个问题如果一旦发生在能够在线支付的网站,那后果不堪设想。难道我们真的希望把“价格未定”弄得像“免费”一样?

用户Jay这么说的:

我经常弄不明白这个0和“无答案”之间的区别。许多次了,我用一个系统的时候它让我输入一个数字,我输入0,然后它居然回我一个错误,说我必须输入一个值!?耍我呢?我不是已经输入了0么?但它就死活说0不行,我估计是因为它根本弄不清楚0和“无”之间的区别。

那如果我们采用第二种保留null的方案的话,网上商店会运行得怎样?很明显,价格为0、莫名其妙的“零元购”将会被从根本上杜绝。

我们可以去对null做一个检查,如果价格为null,那么显示“价格未定”或者“请联系我们”。如果忘记检查了,那就会抛出另一个空指针错误。这种做法当然不讨人喜欢,但是再怎么也比让用户在网上莫名其妙的免费买房子要好。

这样一来,均价的计算也不会出现问题了。

除了这些外,我们还可以发现更多与之类似的问题:

· 在使用String的时候,用空字符串或者用字符串"null"来代替本应该是null的值

· 在使用boolean的时候,用false来代替本应该是null的值

纵观全局,总结如下:

保持用null,远比用非null的值来替代“无值”要好

没错,我们是增加了空指针错误的风险。但是为了避免这种错误,我们所付出的代价就是直接给用户提供完全错误的信息,甚至导致完全无法接受乃至灾难性的后果——比如房子突然被免费“卖”出去了。

-- 如果程序因为空指针错误崩溃了,用户的确会不高兴;

-- 但如果程序完全传达错误的信息并且提供极其愚蠢、不安全的信息给用户,那用户,会更加更加不高兴。

-- 孰轻孰重,一目了然。

所以,我们真的需要对null说一声爱你。


好了,这时候我们回到刚一开始我介绍的email的例子上来。我们如下设置:

String email = null;
System.out.println ( "Alice's email address is " + email );

有如下结果:

Alice's email address is null

在这个场景里,这个结果看起来还是可以接受的。但说实在的程序语言/编译器不应该这么来处理。像我们刚刚分析了,更好的做法应该是抛出一个空指针异常,因为这样一来程序员就可以很快的发现这里有问题。null是个很特殊的东西,所以我们也有必要去对它特殊对待。

经过空指针错误的提醒,程序猿这么一改,就舒服了:

if ( email != null ) {
   System.out.println ( "Alice's email address is " + email );
} else {
   System.out.println ( "Alice doesn't have an email address." );
}

【下一篇文章将分析第二种方案:空对象模式】

null趣谈
Web note ad 1