How to trace a NullPointerException in a chain of getters

后端 未结 11 1540
谎友^
谎友^ 2020-12-03 06:46

If I get a NullPointerException in a call like this:

someObject.getSomething().getSomethingElse().
    getAnotherThing().getYetAnotherObject().getValue();


        
相关标签:
11条回答
  • 2020-12-03 07:43

    You may want to refer to this question about avoiding != null.

    Basically, if null is a valid response, you have to check for it. If not, assert it (if you can). But whatever you do, try and minimize the cases where null is a valid response for this amongst other reasons.

    0 讨论(0)
  • 2020-12-03 07:45

    If you find yourself often writing:

    a.getB().getC().getD().getE();
    

    this is probably a code smell and should be avoided. You can refactor, for example, into a.getE() which calls b.getE() which calls c.getE() which calls d.getE(). (This example may not make sense for your particular use case, but it's one pattern for fixing this code smell.)

    See also the Law of Demeter, which says:

    • Your method can call other methods in its class directly
    • Your method can call methods on its own fields directly (but not on the fields' fields)
    • When your method takes parameters, your method can call methods on those parameters directly.
    • When your method creates local objects, that method can call methods on the local objects.

    Therefore, one should not have a chain of messages, e.g. a.getB().getC().doSomething(). Following this "law" has many more benefits apart from making NullPointerExceptions easier to debug.

    0 讨论(0)
  • 2020-12-03 07:45

    Here's how to find the bug, using Eclipse.

    First, set a breakpoint on the line:

    someObject.getSomething().getSomethingElse().
    getAnotherThing().getYetAnotherObject().getValue();
    

    Run the program in debug mode, allow the debugger to switch over to its perspective when the line is hit.

    Now, highlight "someObject" and press CTRL+SHIFT+I (or right click and say "inspect").

    Is it null? You've found your NPE. Is it non-null? Then highlight someObject.getSomething() (including the parenthesis) and inspect it. Is it null? Etc. Continue down the chain to figure out where your NPE is occurring, without having to change your code.

    0 讨论(0)
  • 2020-12-03 07:46

    Early failure is also an option.

    Anywhere in your code that a null value can be returned, consider introducing a check for a null return value.

    public Foo getSomething()
    {
      Foo result;
      ...
      if (result == null) {
        throw new IllegalStateException("Something is missing");
      }
      return result;
    }
    
    0 讨论(0)
  • 2020-12-03 07:48

    The answer depends on how you view (the contract of) your getters. If they may return null you should really check the return value each time. If the getter should not return null, the getter should contain a check and throw an exception (IllegalStateException?) instead of returning null, that you promised never to return. The stacktrace will point you to the exact getter. You could even put the unexpected state your getter found in the exception message.

    0 讨论(0)
提交回复
热议问题