如何避免非空判断
刚开始编程时,我们经常面对这样的情况,我们不知道也不相信我们的方法协议,所以过多的进行非空检查。而且,我们经常返回null,导致调用者要进行非空检查。
有两种情况会出现非空检查:
1. null是个合法的返回值,对于我们定义的方法协议而言;
2. null不知一个合法的返回值。
情况(2)很简单。我们可以使用assert语句,或者允许方法失败(比如,空指针异常)。断言是一个经常使用的Java特性,在1.4版本添加的。它的语法如下:
asset <condition>
或者
assert <condition> : <object>
<condition>是一个布尔表达式,<object>的toString()方法的返回值就是错误信息。
如果<conditoin>不成立,assert语句会抛出一个Error(AssetionError)。默认情况下,Java会忽略这些断言。你可以通过传递-ea参数给JVM来启用断言。你甚至可以为单独的package或者class启用和禁用断言。也就是说,你可以在开发和测试环境下启用断言,而在生产环境下禁用断言。
这种情况下,不用断言也可以,因为程序一样会失败。唯一的区别是,使用断言会让程序更早的、在更合理的场合失败,同时会提示有意义的信息。
情况(1)有点复杂。如果你不能控制你所调用方法的返回值,那就有点麻烦了。如果null是一个合法的返回值,你就必须去检查它。
如果你能控制你调用的方法,情况就不一样了。避免使用null作为返回值。如果方法的返回值是一个Collection,返回EmptyCollection而不返回null是一个明智的选择。
如果返回值不是集合,就又有点难办了。考虑下面的情况,如果你有这样的接口:
public interface Action {
void doSomething();
}
public interface Parser {
Action findAction(String userInput);
}
Parser接受用户的输入并进行解析,比如实现一个命令行的接口。现在你会允许这个方法返回null,如果没有合法的Action。这就会导致我们说的非空检查。
一个选择是不返回null,而是使用Null Object Pattern:
public class MyParser implements Parser {
private static Action DO_NOTHING = new Action() {
public void doSomething() { /* do nothing */ }
};
public Action findAction(String userInput) {
// ...
if ( /* we can't find any actions */ ) {
return DO_NOTHING;
}
}
}
对比
Parser parser = ParserFactory.getParser();if (parser == null) {
// now what?
// this would be an example of where null isn't (or shouldn't be) a valid response}Action action = parser.findAction(someInput);if (action == null) {
// do nothing} else {
action.doSomething();}
和
arserFactory.getParser().findAction(someInput).doSomething();
后者是一个更好的写法,因为代码更简洁。
也就是说,由findAction()方法抛出一个异常,这个异常含有有意义的信息,这种方式更恰当。它比调用函数抛出一个NullPoninterExceptiong更友好。
try {
ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
userConsole.err(anfe.getMessage());
}
如果你觉得try/catch语句不够简洁,可以构造一个给用户反馈的Action。
public Action findAction(final String userInput) {
/* Code to return requested Action if found */
return new Action() {
public void doSomething() {
userConsole.err("Action not found: " + userInput);
}
}
}
转载于:https://my.oschina.net/kisscoder/blog/667282