我使用object!= null来避免NullPointerException
.
有没有一个很好的替代品呢?
例如:
if (someobject != null) {
someobject.doCalc();
}
当不知道对象是否为null时,这可以避免NullPointerException.
请注意,接受的答案可能已过期,请参阅https://*.com/a/2386013/12943以获取更新的方法.
解决方法:
这对我来说听起来像是一个相当普遍的问题,初级到中级开发人员往往会在某些方面面临这样的问题:他们要么不知道,要么不信任他们参与的合同,并且防御性地过度检查空值.此外,在编写自己的代码时,它们倾向于依赖返回空值来指示某些内容,从而要求调用者检查空值.
换句话说,有两个实例进行空检查:
>如果null是合同方面的有效回复;和
>哪里不是有效的回复.
(2)很容易.使用断言语句(断言)或允许失败(例如,NullPointerException).断言是1.4中添加的高度未充分利用的Java功能.语法是:
assert <condition>
要么
assert <condition> : <object>
其中< condition>是一个布尔表达式,< object>是一个对象,其toString()方法的输出将包含在错误中.
如果条件不为真,则assert语句抛出Error(AssertionError).默认情况下,Java会忽略断言.您可以通过将选项-ea传递给JVM来启用断言.您可以为各个类和包启用和禁用断言.这意味着您可以在开发和测试时使用断言验证代码,并在生产环境中禁用它们,尽管我的测试表明,断言没有性能影响.
在这种情况下不使用断言是可以的,因为代码只会失败,如果使用断言将会发生这种情况.唯一的区别是,断言可能会更快地发生,以更有意义的方式发生,并且可能带有额外的信息,这可能会帮助您弄清楚如果您没有预料到它会发生的原因.
(1)有点难.如果您无法控制您正在调用的代码,那么您就会陷入困境.如果null是有效响应,则必须检查它.
如果它是你控制的代码(然而通常就是这种情况),那么这是一个不同的故事.避免使用空值作为响应.使用返回集合的方法,很容易:几乎一直返回空集合(或数组)而不是null.
对于非收藏品,它可能会更难.以此为例:如果您有这些接口:
public interface Action {
void doSomething();
}
public interface Parser {
Action findAction(String userInput);
}
其中Parser接受原始用户输入并找到要做的事情,也许是在为某些事情实现命令行界面时.现在,如果没有适当的操作,您可以使合同返回null.这导致你正在谈论的空检查.
另一种解决方案是永远不会返回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();
}
至
ParserFactory.getParser().findAction(someInput).doSomething();
这是一个更好的设计,因为它导致更简洁的代码.
也就是说,也许findAction()方法完全适合抛出带有意义错误消息的异常 – 特别是在你依赖用户输入的情况下.对于findAction方法抛出一个Exception比调用方法爆炸一个没有解释的简单NullPointerException要好得多.
try {
ParserFactory.getParser().findAction(someInput).doSomething();
} catch(ActionNotFoundException anfe) {
userConsole.err(anfe.getMessage());
}
或者,如果您认为try / catch机制太难看,而不是Do Nothing,则默认操作应该向用户提供反馈.
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);
}
}
}