简体   繁体   English

Java Null参考最佳实践

[英]Java Null Reference Best Practice

In java, Which of the following is the more "accepted" way of dealing with possibly null references? 在java中,以下哪一种处理可能为空的引用的方式更为“可接受”? note that a null reference does not always indicate an error... 请注意,空引用并不总是表示错误...

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

or 要么

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

The answers already given are excellent (don't use exceptions for control flow; exceptions are expensive to throw and handle). 已经给出的答案非常好(不要使用控制流的例外;抛出和处理的例外是昂贵的)。 There's one other important reason specifically not to catch NullPointerException . 还有另一个重要的原因,特别是没有捕获NullPointerException

Consider a code block that does the following: 考虑执行以下操作的代码块:

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

This might seem like a safe way to handle nullity of reference ...but what if reference was non-null and someMethod() raised NPE? 这似乎是一种处理reference无效的安全方法......但是如果引用是非null而someMethod()引发了NPE呢? Or what if there was a NPE raised elsewhere in the try block? 或者如果在try块中的其他位置引发了NPE会怎么样? Catching NPE is a surefire way to prevent bugs from being found and fixed. 捕获NPE是防止错误被发现和修复的可靠方法。

Catching exceptions is relatively expensive. 捕获异常相对昂贵。 It's usually better to detect the condition rather than react to it. 通常最好是检测条件而不是对它做出反应。

Of course this one 当然是这一个

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

we shouldn't rely on exception for decision making, that aren't given for that purpose at all, also they are expensive. 我们不应该依赖于例外的决策,而这些例外根本不是为了这个目的而给出的,它们也很昂贵。


Well If you aren't making decision and just verifying for initialized variable then 那么如果您没有做出决定并且只是验证初始化变量那么

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

I have seen some auto code generator wraps up this thing in accessors/getter method. 我看到一些自动代码生成器在accessors / getter方法中包装了这个东西。

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

From the answers its clear that catching an exception is not good. 从答案中可以清楚地看出,抓住异常并不好。 :) Exceptions are definitely not free of cost. :)例外肯定不是免费的。 This might help you to understand it in depth. 这可能有助于您深入理解它。 .

I would also like to mention an another practice while comparing your object with a known value. 我还想在将您的对象与已知值进行比较时提及另一种做法。
This is the traditional way to do the job: (check whether the object is null or not and then compare) 这是完成这项工作的传统方法:(检查对象是否为null然后进行比较)

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

but in this way, you dont have to bother about your object: 但是这样,你不必为你的对象烦恼:

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

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

The first form: 第一种形式:

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

You should not use exceptions for control flow. 您不应该使用控制流的异常。

Exceptions are for handling exceptional circumstances that would not normally occur during normal operating conditions. 例外情况是处理在正常操作条件下通常不会发生的特殊情况。

You should use exception catching where you do not expect there to be an error. 您应该使用异常捕获,而不希望出现错误。 If something can be null, then you should check for that. 如果某些东西可以为null,那么你应该检查一下。

maybe the try catch approach will start making sense in this situation when we can start doing 也许在我们可以开始做的时候,try catch方法会在这种情况下开始变得有意义

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

This is related to your style of development, if you are developing code using "safe" style you have to use 如果您使用必须使用的“安全”样式开发代码,这与您的开发风格有关

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

but if you do not use this style at least you should catch exception, but in this case it NullPointerException and I think preferably to check input parameters to null and not wait to throwing exception. 但是如果你不使用这种风格至少应该捕获异常,但在这种情况下它是NullPointerException,我认为最好将输入参数检查为null而不是等待抛出异常。

Since you asked for Best Practices, I want to point out that Martin Fowler suggests to introduce a subclass for null references as best practice. 既然你要求最佳实践,我想指出Martin Fowler建议引入一个空引用的子类作为最佳实践。

public class NullCustomer extends Customer {}

Thus, you avoiding the hassle of dealing with NullPointerException's, which are unchecked. 因此,您可以避免处理未经检查的NullPointerException的麻烦。 Methods which might return a Customer value of null, would then instead return a NullCustomer instead of null. 可能返回Customer值为null的方法将返回NullCustomer而不是null。

Your check would look like: 你的支票看起来像:

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

In my opinion, it is permissible in some cases to catch a NullPointerException to avoid complex checks for null references and enhance code readability, eg 在我看来,在某些情况下允许捕获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 );
}

An argument against it is that by checking for individual members being null, you can write a more detailed error message, but that is often not necessary. 反对它的一个论点是,通过检查单个成员为空,您可以编写更详细的错误消息,但这通常是没有必要的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM