2012-01-26 15 views
8

我经常看到java SourceCode,其中方法或构造函数的值为null是不允许的。一个典型的实现的,这看起来像是否有意义自我检查Java中的空值

public void someMethod(Object someObject){ 

    if(someObject == null) throw new NullPointerException() 

    someObject.aMethodCall() 

} 

我在看毫无意义为自己所有,因为如果我尝试调用方法上的空指针的NullPointerException反正是抛出。如果此方法会抛出IllegalArgumentException或其他一些自定义异常,我会看到这种感觉。有人可以清理,为什么这个检查似乎是有道理的(正如我经常看到的那样,我经常假设,必须有这种感觉),或为什么它是完全废话

+0

这是没用的,如果正确的行为是空指针(事实上它更糟,因为检查需要一点时间)。 – Jim

+0

显式的空检查与JIT之后的隐式空检查一样便宜,所以我不担心这里的性能。 –

+0

可能的重复:http://stackoverflow.com/questions/32280/passing-null-to-a-method我喜欢断言参数善良检查,就像在Ada中使用前提条件。 – vulkanino

回答

9

您发布的代码完全没有意义。它看起来像是一个强大的案例cargo cult programming。最有可能的是,有人实施了一次有用的测试来检查先决条件,而其他人则将测试看作是这样的。

4

这取决于谁是负责恢复从这种情况。如果是来电者,请投入NPE。如果是被调用的方法,则测试null并执行任何必要的操作来解决这种情况。

编辑:不要明确抛出NPE,只是让它冒出来。对于模糊的措辞,抱歉。

+0

但是,在OP给出的例子的情况下,显然这种方法本身并没有从异常中恢复...... – cdeszaq

+0

是的,但我只是把它作为MWE而不是真正的代码。 – 2012-01-26 13:15:37

+0

抛出未经检查的异常是不好的编程习惯...... –

5

不,这并没有什么意义,但仅仅是因为抛出一个NPE不会添加任何有用的信息。

你可以做的更好的错误抛出(例如)一个IllegalStateException:

if (someObject == null) throw new IllegalStateException("someObject was null"); 

但是,这并不增加的巨大价值或者 - 不是作为具体什么是另外null(可可用于更复杂的方法)

+0

可能的异常应在'throws'子句中声明并记录。 –

5

当然,你想检查为空。这是您方法的前提条件,是与客户签订合同的一部分。如果你的方法不能接受null输入,你需要强制执行。

异常的选择可能会更好。我通常会使用IllegalArgumentException

如果这是简单的方法,困扰你,我不得不说我同意。那里没有新的信息。

+0

我不相信'IllegalArgumentException'是更好的选择。 'NPE'更具体。你也可以参考Effective Java的60项。 –

+0

我会看看,但我不知道我是否同意。 IAE的信息可以清楚地说明。它也可以标记其他条件(例如,既不能为空也不为空的字符串)。你的解释很窄,但对这个问题是正确的。 – duffymo

0

我认为如果一个方法处理时需要花费很多时间或在实际触发NPE之前难以撤消,那么这种检查是有意义的。在给出的例子中,我不认为这是真实的。

另一方面:使用断言或抛出一个更具体的异常,如IllegalArgumentException可能更有意义。

0

在C#中存在一个ArgumentNullException。此异常在构造函数中使用参数的名称。所以调用者可以看到,哪个参数可能是不合法的NULL。 IllegalArgumentException几乎与Java相当。

2

你描述,可按以下假设之一下是有用的情况:

1)如果你有做一些操作,它们要么昂贵还是执行之前改变一些全局状态someObject.aMethodCall()可以防止回滚代码和浪费执行周期。

2.)如果someObject存储在一个数据结构中,如果稍后从数据结构中检索到数据,则可能会产生一个可能的错误。我想,我记得java收集框架中的一些类,它抛出了一个NPE,而不是将空值放入存储结构中。

+0

来自Java集合的一个例子:一个空的TreeSet的旧版本允许添加null,只有在添加第二个元素时抛出一个NPE。当前版本的'TreeSet.add'显式检查'null'。 –

6

有一个角落的情况下,这样的事情是有道理的。如果您不立即使用someObject,则将错误情况短路到该函数的开始会很有用。

public void someMethod(Object someObject){ 

    if(someObject == null) throw new NullPointerException(); 

    expensiveOperationNotUsingSomeObject(); 

    someObject.aMethodCall(); 
} 
+1

+1一张支票和显式掷*可以*有用。快速思考失败,尽早失败。 – Qwerky

2

个人为什么我从来没有抛出NullPointerException作为公共API方法的一部分的原因是因为它使得它更难的程序员在自己身边一个编程错误,在我的代码中的错误区分(即我是否刻意让NPE被抛出?)。

抛出一个不同的异常使意图更加清晰,同时也帮助程序员更容易地发现错误。所以我会在那里用IllegalArgumentException

如果是一些内部方法?我会使用断言或让它崩溃。没有意义明确地抛出NPE imo。