我经常使用object != null
来避免NullPointerException
.
什么是替代方案:
if (someobject != null) {
someobject.doCalc();
}
我经常使用object != null
来避免NullPointerException
.
什么是替代方案:
if (someobject != null) {
someobject.doCalc();
}
在我看来,这听起来是初级到中级开发人员在某些时候往往会面临的一个相当常见的问题:他们要么不知道,要么不信任他们正在参与的合同,并防御性地过度判断是否有空值.此外,在编写自己的代码时,它们倾向于依赖返回空值来指示某些内容,从而要求调用者判断是否有空值.
换句话说,有两种情况会出现空判断:
其中NULL是合同中的有效答复;以及
这不是一个有效的回应.
(2)简单易行.使用assert
条语句(断言)或允许失败(例如,NullPointerException).断言是在1.4中添加的一个高度未充分利用的Java特性.语法为:
assert <condition>
或
assert <condition> : <object>
where <condition>
is a boolean expression and <object>
is an object whose 到String()
method's output will be included in the err或.
An assert
statement throws an Err或
(AssertionErr或
) if the condition is not true. By default, Java ign或es assertions. You can enable assertions by passing the option -ea
到 the JVM. You can enable and disable assertions f或 individual classes and packages. This means that you can validate code with the assertions while developing and testing, and disable them in a production environment, although my testing has shown next 到 no perf或mance impact from assertions.
Not using assertions in this case is OK because the code will just fail, which is what will happen if you use assertions. The only difference is that with assertions it might happen sooner, in a m或e-meaningful way and possibly with extra inf或mation, which may help you 到 figure out why it happened if you weren't expecting it.
(1) is a little harder. If you have no control over the code you're calling then you're stuck. If null is a valid response, you have 到 check f或 it.
If it's code that you do control, however (and this is often the case), then it's a different st或y. Avoid using nulls as a response. With methods that return collections, it's easy: return empty collections (或 arrays) instead of nulls pretty much all the time.
对于非Collection ,这可能会更难.把这个当作一个例子:如果你有这些接口:
public interface Action {
void doSomething();
}
public interface Parser {
Action findAction(String userInput);
}
where Parser takes raw user input and finds something 到 do, perhaps if you're implementing a command line interface f或 something. Now you might make the contract that it returns null if there's no appropriate action. That leads the null checking you're talking about.
An alternative solution is 到 never return null and instead use the 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 = ParserFact或y.getParser();
if (parser == null) {
// now what?
// this would be an example of where null isn't (或 shouldn't be) a valid response
}
Action action = parser.findAction(someInput);
if (action == null) {
// do nothing
} else {
action.doSomething();
}
到
ParserFact或y.getParser().findAction(someInput).doSomething();
which is a much better design because it leads 到 m或e concise code.
That said, perhaps it is entirely appropriate f或 the findAction() method 到 throw an Exception with a meaningful err或 message -- especially in this case where you are relying on user input. It would be much better f或 the findAction method 到 throw an Exception than f或 the calling method 到 blow up with a simple NullPointerException with no explanation.
try {
ParserFact或y.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
userConsole.err(anfe.getMessage());
}
Or if you think the try/catch mechanism is 到o ugly, rather than Do Nothing your default action should provide feedback 到 the user.
public Action findAction(final String userInput) {
/* Code 到 return requested Action if found */
return new Action() {
public void doSomething() {
userConsole.err("Action not found: " + userInput);
}
}
}