Java Null参考最佳实践

时间:2011-05-13 12:23:00

标签: java coding-style

在java中,以下哪一种处理可能为空的引用的方式更为“可接受”?请注意,空引用并不总是表示错误...

if (reference == null) {
    //create new reference or whatever
}
else {
    //do stuff here
}

try {
    //do stuff here
}
catch (NullPointerException e) {
    //create new reference or whatever
}

11 个答案:

答案 0 :(得分:14)

已经给出的答案非常好(不要使用控制流的例外;抛出和处理的例外是昂贵的)。另外还有一个重要的原因,特别是没有抓住NullPointerException

考虑执行以下操作的代码块:

try {
    reference.someMethod();
    // Some other code
}
catch (NullPointerException e) {
    // 'reference' was null, right? Not so fast...
}

这似乎是一种处理reference无效的安全方法......但如果引用为非null且someMethod()提升了NPE,该怎么办?或者,如果在try区块的其他位置引发了NPE,该怎么办?捕获NPE是防止错误被发现和修复的必然方法。

答案 1 :(得分:11)

捕获异常相对昂贵。通常最好是检测条件而不是对它做出反应。

答案 2 :(得分:7)

当然是这个

if (reference == null) {
    //create new reference or whatever
}
else {
    //do stuff here
}

我们不应该依赖于例外的决策,而这些例外根本不是为了这个目的,也是昂贵的。


那么如果您没有做出决定而只是验证初始化变量,那么

if (reference == null) {
    //create new reference or whatever
}
//use this variable now safely  

我看到一些自动代码生成器在accessors / getter方法中包装了这个东西。

答案 3 :(得分:2)

我认为一般情况下应该为异常情况保留一个例外 - 如果有时需要空引用,则应检查并明确处理它。

答案 4 :(得分:2)

从答案中可以清楚地看出,抓住异常并不好。 :) 例外肯定不是免费的。 This might help you to understand it in depth.

我还想在将您的对象与已知值进行比较时提及另一种做法 这是完成这项工作的传统方式:(检查对象是否为空,然后进行比较)

Object obj = ??? //We dont know whether its null or not.
if(obj!=null && obj.equals(Constants.SOME_CONSTANT)){
    //your logic
}

但是通过这种方式,你不必为你的目标而烦恼:

Object obj = ???
if(Constants.SOME_CONSTANT.equals(obj)){  //this will never throw 
                                          //nullpointer as constant can not be null.
}

答案 5 :(得分:1)

第一个,抛出异常是一项代价高昂的操作。

答案 6 :(得分:1)

第一种形式:

if (reference == null)
{    
    //create new reference or whatever
}
else 
{    
    //do stuff here
}

您不应该使用控制流的例外。

例外情况是处理在正常操作条件下通常不会发生的特殊情况。

答案 7 :(得分:0)

您应该使用异常捕获,而不希望出现错误。如果可以为空,那么你应该检查一下。

答案 8 :(得分:0)

当我们开始做

时,尝试捕捉方法可能会在这种情况下开始变得有意义
try {
  //do stuff here
}
catch (NullPointerException e) {
  //create new reference or whatever
  retry;
}

答案 9 :(得分:0)

这与您的开发风格有关,如果您使用“安全”风格开发代码,则必须使用

    if(null == myInstance){
// some code    
    }else{
// some code
    }

但是如果你不使用这种风格至少你应该捕获异常,但在这种情况下它是NullPointerException,我认为最好将输入参数检查为null而不是等待抛出异常。

答案 10 :(得分:0)

由于您要求最佳实践,我想指出Martin Fowler建议引入空引用的子类作为最佳实践。

public class NullCustomer extends Customer {}

因此,您可以避免处理未经检查的NullPointerException的麻烦。可能返回Customer值为null的方法将返回NullCustomer而不是null。

您的支票如下:

final Customer c = findCustomerById( id );
if ( c instanceof NullCustomer ) {
    // customer not found, do something ...
} else {
    // normal customer treatment
    printCustomer( c );
}

在我看来,在某些情况下允许捕获NullPointerException以避免对空引用的复杂检查并增强代码可读性,例如。

private void printCustomer( final Customer c ) {
try {
    System.out.println( "Customer " + c.getSurname() + " " + c.getName() + "living in " +     c.getAddress().getCity() + ", " + c.getAddress().getStreet() );
} catch ( NullPointerException ex ) {
    System.err.println( "Unable to print out customer information.", ex );
}

反对它的论点是,通过检查单个成员为空,您可以编写更详细的错误消息,但这通常是没有必要的。