Should I throw a NullPointerException explicitly or let Java do it for me?

As the title says, I am wondering what the best practice is regarding the throwing of NullPointerExceptions. Specifically, if I have an external library function that can return null in circumstances that I don't want to actually handle (see below for a specific example), as the null indicates a problem with the software. The question is, should I

  • check the return value for null and throw the NullPointerException myself, or
  • should I just let Java do the dirty work for me as soon as I try to use the object.
  • The first approach lets me add some additional information, since I get to construct the NullPointerException, but the second makes for cleaner code in my opinion. I would also wonder as to any performance implications, that is, is Java more efficient at throwing the NPE "natively"?

    By way of example, I am trying to use the Java Speech API to create a speech synthesizer using the following code:

    synthesizer = Central.createSynthesizer(generalDesc);
    
    if (synthesizer == null) {
        // (1) throw NPE explicitly
        throw new NullPointerException("No general domain synthesizer found.");
    }
    
    // (2) let the JVM throw the NPE when dereferencing
    synthesizer.allocate();
    

    Central.createSynthesizer returns null if it cannot find a suitable synthesizer, which is most often caused by a missing speech.properties file. So it's a matter of wrong setup of the system, and pretty unrecoverable from at runtime, rather than circumstances that need to be handled programmatically. As such, I believe throwing a NullPointerException is a valid response, since it indicates a bug (not in the code but in the deployment of the software). But since the synthesizer object is dereferenced in the very next statement, should I just let the JVM throw the NPE for me and save the null check?

    Addendum: Considering that speech.properties gets loaded when the JVM starts needs to exist on the filesystem in (normally) "user.home" or "java.home/lib", it is puzzling that createSynthesizer doesn't straight up throw an NPE (which is what I had written originally in a Freudian slip) when it fails to find it but returns null instead. I think that throwing a NullPointerException is the right thing to do here, because it indicates an actual bug in the deployment of the software.


    In your case: neither. Check for null and throw more meaningful exception, not NPE.

    In general - if NPE should not occur, don't test for it explicitly, Java will do it for you. Less tests to write, less code to read, less complexity to analyze.

    However if null is expected test it as soon as possible and interpret accordingly. Otherwise NullPointerException will occur somewhere later in different line/method, making it harder to debug the real problem.


    I'd say that you should never explicitly create a NullPointerException and instead use an exception type that more clearly describes the situation. In your case, I'd say IllegalStateException would fit the situation "wrong setup of the system, and pretty unrecoverable from at runtime". Or you could create your own ComponentMissingException . In cases where a required method parameter is null , IllegalArgumentException is typically used.


    I dont like having null be a valid return value, even in "exceptional circumstances". So I take yet another approach.

    In your case I'd annotate the method createSynthesizer(...) with @NotNull (@NotNull is an amazing annotation). Instead of an NPE, I'd get an IllegalStateException as soon as createSynthesizer(...) would want to return null.

    You'd get a:

    java.lang.IllegalStateException: @NotNull method .../.../createSynthetiser(...) must not return null
    

    There are several benefits to this approach:

  • both NullPointerException and IllegalStateException extends RuntimeException so you're not fundamentally changing your program

  • the exception shall be thrown immediately where the error happens (not later on, once you either check/throw yourself or once you try to dereference null)

  • you don't need to bother writing the if ... == null / throw part anymore.

  • As a, gigantic, added benefit some IDE (like IntelliJ IDEA) will warn you in real-time about probable @NotNull violations.

    链接地址: http://www.djcxy.com/p/76214.html

    上一篇: 使用compareTo实现equals方法

    下一篇: 我应该显式抛出一个NullPointerException,还是让Java为我做?